Revision: 4584 http://sourceforge.net/p/vexi/code/4584 Author: clrg Date: 2013-11-20 17:46:52 +0000 (Wed, 20 Nov 2013) Log Message: ----------- BoxRenderProperties renamed to BoxVisual
Modified Paths: -------------- branches/vexi3/org.vexi-core.main/src/main/jpp/org/vexi/core/Box.jpp Added Paths: ----------- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxVisual.java Removed Paths: ------------- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxRenderProperties.java Deleted: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxRenderProperties.java =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxRenderProperties.java 2013-11-20 15:47:48 UTC (rev 4583) +++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxRenderProperties.java 2013-11-20 17:46:52 UTC (rev 4584) @@ -1,440 +0,0 @@ -// Copyright 2000-2008 the Contributors, as shown in the revision logs. -// Licensed under the GNU General Public License version 2 ("the License"). -// You may not use this file except in compliance with the License. - -package org.vexi.core; - -import org.ibex.js.Fountain; -import org.ibex.js.JS; -import org.ibex.js.JSExn; -import org.ibex.js.JSString; -import org.ibex.js.JSU; -import org.vexi.graphics.Color; -import org.vexi.graphics.Font; -import org.vexi.graphics.Picture; - -/** - * amalgamates Box rendering properties for memory/runtime efficiency - * - text properties font, fontsize, text, textcolor - * - fill properties texture, fillcolor - **/ -final class BoxRenderProperties implements Constants { - - //////// INSTANCE PROPERTIES ///////////////////////////////////// - - private short flags = 0; - int fontsize = 0; - int fillcolor = DEFAULT_FILLCOLOR; - int textcolor = DEFAULT_COLOR; - short textwidth = 0; - short textheight = 0; - Font font = DEFAULT_FONT; - JSString text = EMPTY_STRING; - Picture texture = null; - - - //////// CONSTRUCTORS ///////////////////////////////////////////// - - /** construct default text */ - BoxRenderProperties() { } - - /** construct new text object based on font from 'stream' of size 'pointsize' */ - BoxRenderProperties(JS stream) { - set(FONTSTREAM_SET); - setFont(stream, MEDIUM_SIZE); - } - - /** construct new text object based on font from 'stream' of size 'pointsize' */ - BoxRenderProperties(int pointsize) { - set(FONTSIZE_SET); - setFont(DEFAULT_STREAM, pointsize); - } - - - //////// STATIC CONTENT /////////////////////////////////////////// - - private static final short FILLCOLOR_SET = 0x0001; - private static final short FONTCOLOR_SET = 0x0002; - private static final short FONTSIZE_SET = 0x0004; - private static final short FONTSTREAM_SET = 0x0008; - - private static final short FONT_TRAP = 0x0010; - private static final short FONTSIZE_TRAP = 0x0020; - - static int XXSMALL_OFFSET = -8; - static int XSMALL_OFFSET = -4; - static int SMALL_OFFSET = -2; - static int MEDIUM_SIZE = 10; - static int LARGE_OFFSET = 4; - static int XLARGE_OFFSET = 8; - static int XXLARGE_OFFSET = 14; - - static int DEFAULT_COLOR = 0xFF000000; - static int DEFAULT_FILLCOLOR = 0x00000000; - static Fountain DEFAULT_STREAM = Main.vera; - static Font DEFAULT_FONT = Font.getFont(DEFAULT_STREAM, MEDIUM_SIZE); - static BoxRenderProperties DEFAULT_RENDER_PROPS = new BoxRenderProperties(); - static JSString EMPTY_STRING = (JSString) JSU.S("", true); - - static int getDefaultFontSize() { return MEDIUM_SIZE; } - static Fountain getDefaultStream() { return DEFAULT_STREAM; } - static Font getDefaultFont() { return DEFAULT_FONT; } - - /** access for controlling default pointsize */ - static boolean setDefaultPointsize(int pointsize) { - if (pointsize == MEDIUM_SIZE) { - return false; - } - MEDIUM_SIZE = pointsize; - DEFAULT_FONT = Font.getFont(DEFAULT_STREAM, MEDIUM_SIZE); - return true; - } - - /** access for controlling default stream */ - static boolean setDefaultStream(Fountain stream) { - if (stream == DEFAULT_STREAM) { - return false; - } - DEFAULT_STREAM = stream; - DEFAULT_FONT = Font.getFont(DEFAULT_STREAM, MEDIUM_SIZE); - return true; - } - - /** return appropriate JS constant for size */ - static JS sizeToJS(int pointsize) { - switch (pointsize) { - case -3: return SC_xxsmall; - case -2: return SC_xsmall; - case -1: return SC_small; - case 0: return SC_medium; - case 1: return SC_large; - case 2: return SC_xlarge; - case 3: return SC_xxlarge; - default: return JSU.N(pointsize); - } - } - - /** convert size represented in JS to appropriate pointsize */ - static int jsToPointsize(JS size) throws JSExn { - return normalizeSize(jsToSize(size)); - } - - /** convert size represented in JS to appropriate integer value */ - static int jsToSize(JS size) throws JSExn { - if (size==null) { - return MEDIUM_SIZE; - } - if (size.type()==SC_number) { - int ps = JSU.toInt(size); - if (ps<6) { - throw new JSExn("Minimum fontsize is 6 - set to null or 'medium' for default size"); - } - return ps; - } else { - if (size.type()!=SC_string) { - throw new JSExn("type not applicable for fontsize: '"+size.type()+"'"); - } - } - String sizeStr = JSU.toString(size); - try { - switch (sizeStr.charAt(0)) { - case 'm': - if (sizeStr.equals("medium")) { - return 0; - } - case 's': - if (sizeStr.equals("small")) { - return -1; - } - case 'l': - if (sizeStr.equals("large")) { - return 1; - } - case 'x': - if (sizeStr.charAt(1) == 'x') { - if (sizeStr.equals("xxsmall")) {// || sizeStr.equals("xx-small")) { - return -3; - } - if (sizeStr.equals("xxlarge")) {// || sizeStr.equals("xx-large")) { - return 3; - } - } else { - if (sizeStr.equals("xsmall")) {// || sizeStr.equals("x-small")) { - return -2; - } - if (sizeStr.equals("xlarge")) {// || sizeStr.equals("x-large")) { - return 2; - } - } - default: - return Integer.parseInt(sizeStr, 10); - } - } catch (Exception e) { - throw new JSExn("illegal fontsize: "+sizeStr+""); - } - } - - /** check/convert offset pointsize to literal pointsize */ - static final int normalizeSize(int pointsize) { - if (pointsize>5) { - return pointsize; - } - int ps = MEDIUM_SIZE; - switch (pointsize) { - case -3: ps += XXSMALL_OFFSET; break; - case -2: ps += XSMALL_OFFSET; break; - case -1: ps += SMALL_OFFSET; break; - case 0: break; - case 1: ps += LARGE_OFFSET; break; - case 2: ps += XLARGE_OFFSET; break; - case 3: ps += XXLARGE_OFFSET; break; - } - return ps>5 ? ps : 6; - } - - - //////// HELPER FUNCTIONS ///////////////////////////////////////// - - // FLAGS helper functions - private final void set(short mask) { flags |= mask; } - private final void clear(short mask) { flags &= ~mask; } - private final boolean test(short mask) { return ((flags & mask) == mask); } - - boolean activeTrapFontsize() { return test(FONTSIZE_TRAP); } - void clearTrapFont() { clear(FONT_TRAP); } - void clearTrapFontsize() { clear(FONTSIZE_TRAP); } - void setTrapFont(Box owner) { - if (this == DEFAULT_RENDER_PROPS) { - BoxRenderProperties t = new BoxRenderProperties(); - t.set(FONT_TRAP); - owner.renderprops = t; - } else { - set(FONT_TRAP); - } - } - void setTrapFontsize(Box owner) { - if (this == DEFAULT_RENDER_PROPS) { - BoxRenderProperties t = new BoxRenderProperties(); - t.set(FONTSIZE_TRAP); - owner.renderprops = t; - } else { - set(FONTSIZE_TRAP); - } - } - - private final void setFont(JS stream, int pointsize) { - if (stream == font.stream && pointsize == this.fontsize) { - return; - } - font = Font.getFont(stream, normalizeSize(pointsize)); - this.fontsize = pointsize; - calculateDimensions(); - } - - /** set fillcolor to arbitrary value */ - private boolean setFillcolor(int fillcolor, Box owner) { - if (test(FILLCOLOR_SET) && fillcolor == this.fillcolor) { - return false; - } - if (this == DEFAULT_RENDER_PROPS) { - BoxRenderProperties t = new BoxRenderProperties(); - t.fillcolor = fillcolor; - t.set(FILLCOLOR_SET); - owner.renderprops = t; - } else { - set(FILLCOLOR_SET); - this.fillcolor = fillcolor; - if (texture != null) { - texture = null; - } - } - return true; - } - - private boolean setTexture(Picture texture, Box owner) { - if (texture == this.texture) { - return false; - } - if (this == DEFAULT_RENDER_PROPS) { - BoxRenderProperties t = new BoxRenderProperties(); - t.texture = texture; - owner.renderprops = t; - } else { - this.texture = texture; - // set fillcolor to be transparent - fillcolor = DEFAULT_FILLCOLOR; - clear(FILLCOLOR_SET); - } - return true; - } - - - //////// INSTANCE FUNCTIONS /////////////////////////////////////// - - boolean isEmpty() { return text == EMPTY_STRING; } - boolean isDefaultSize() { return !test(FONTSIZE_SET); } - boolean isDefaultColor() { return !test(FONTCOLOR_SET); } - boolean isDefaultStream() { return !test(FONTSTREAM_SET); } - - /** set textcolor to default color - * @return boolean stating if textcolor has changed */ - boolean resetTextcolor() { - if (this != DEFAULT_RENDER_PROPS && test(FONTCOLOR_SET)) { - textcolor = DEFAULT_COLOR; - clear(FONTCOLOR_SET); - return true; - } - return false; - } - - /** set textcolor using arbitrary string, converting as necessary - * @return boolean stating if textcolor has changed */ - boolean setTextcolor(JS jstextcolor, Box owner) throws JSExn { - int c = Color.stringToColor(JSU.toString(jstextcolor)); - return setTextcolor(c, owner); - } - - /** set textcolor to integer value - * @return boolean stating if textcolor has changed */ - boolean setTextcolor(int textcolor, Box owner) { - if (test(FONTCOLOR_SET) && textcolor == this.textcolor) { - return false; - } - if (this == DEFAULT_RENDER_PROPS) { - BoxRenderProperties t = new BoxRenderProperties(); - t.set(FONTCOLOR_SET); - t.textcolor = textcolor; - owner.renderprops = t; - } else { - set(FONTCOLOR_SET); - this.textcolor = textcolor; - } - return true; - } - - /** set the fill of a box according to 'value', converting as necessary */ - boolean setFill(JS value, Box owner) throws JSExn { - if (value == null) { - return resetFill(); - } else if (JSU.isString(value)) { - // use as a hex colour value - int newfillcolor = Color.stringToColor(JSU.toString(value)); - return setFillcolor(newfillcolor, owner); - } else { - // stream fill - load texture - Picture newtex = Picture.load(value, owner); - // REMARK - Box.run() depends on renderprops - // so we need to call setTexture() before it - boolean textureChanged = setTexture(newtex, owner); - if (textureChanged && newtex.isLoaded) { - owner.run(null); - } - return textureChanged; - } - } - - /** set fillcolor to default fillcolor */ - boolean resetFill() { - if (texture==null && !test(FILLCOLOR_SET)) { - return false; - } - // set fillcolor to be transparent - fillcolor = DEFAULT_FILLCOLOR; - clear(FILLCOLOR_SET); - texture = null; - return true; - } - - /** set pointsize of this text object */ - boolean resetFontsize() { - if (test(FONTSIZE_SET) && this != DEFAULT_RENDER_PROPS) { - if (fontsize != MEDIUM_SIZE) { - setFont(font.stream, MEDIUM_SIZE); - } - clear(FONTSIZE_SET); - return true; - } - return false; - } - - /** set pointsize to arbitary value */ - boolean setFontsize(JS jsfontsize, Box owner) throws JSExn { - int ps = jsToSize(jsfontsize); - return setFontsize(ps, owner); - } - boolean setFontsize(int fontsize, Box owner) { - if (test(FONTSIZE_SET) && fontsize == this.fontsize) { - return false; - } - if (this == DEFAULT_RENDER_PROPS) { - owner.renderprops = new BoxRenderProperties(fontsize); - } else { - set(FONTSIZE_SET); - if (fontsize<6 || fontsize != this.fontsize) { - setFont(font.stream, fontsize); - } - } - return true; - } - - /** set font stream of this text object */ - boolean resetStream() { - if (this != DEFAULT_RENDER_PROPS && test(FONTSTREAM_SET)) { - if (font.stream != DEFAULT_STREAM) { - setFont(DEFAULT_STREAM, fontsize); - } - clear(FONTSTREAM_SET); - return true; - } - return false; - } - - /** set stream to arbitrary font stream */ - boolean setStream(JS stream, Box owner) { - if (test(FONTSTREAM_SET) && stream == font.stream) { - return false; - } - if (this == DEFAULT_RENDER_PROPS) { - owner.renderprops = new BoxRenderProperties(stream); - } else { - set(FONTSTREAM_SET); - setFont(stream, fontsize); - } - return true; - } - - /** set string representing text object */ - //void resetString() { return setString(EMPTY_STRING); } - boolean setString(JSString text, Box owner) { - if (text==null) { - text = EMPTY_STRING; - } - if (text.equals(this.text)) { - return false; - } - if (this == DEFAULT_RENDER_PROPS) { - BoxRenderProperties t = new BoxRenderProperties(); - owner.renderprops = t; - t.text = text; - t.calculateDimensions(); - } else { - this.text = text; - calculateDimensions(); - } - return true; - } - - /** establish dimensions of rendered text contents */ - private void calculateDimensions() { - if (text == EMPTY_STRING) { - textwidth = 0; - textheight = 0; - return; - } - long textsize = font.textsize(text.toString()); - int iwidth = (int)((textsize >>> 32) & 0xffffffff); - int iheight = (int)(textsize & 0xffffffffL); - textwidth = iwidth > Short.MAX_VALUE ? Short.MAX_VALUE : (short)iwidth; - textheight = iheight > Short.MAX_VALUE ? Short.MAX_VALUE : (short)iheight; - } -} Copied: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxVisual.java (from rev 4581, branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxRenderProperties.java) =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxVisual.java (rev 0) +++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/BoxVisual.java 2013-11-20 17:46:52 UTC (rev 4584) @@ -0,0 +1,440 @@ +// Copyright 2000-2008 the Contributors, as shown in the revision logs. +// Licensed under the GNU General Public License version 2 ("the License"). +// You may not use this file except in compliance with the License. + +package org.vexi.core; + +import org.ibex.js.Fountain; +import org.ibex.js.JS; +import org.ibex.js.JSExn; +import org.ibex.js.JSString; +import org.ibex.js.JSU; +import org.vexi.graphics.Color; +import org.vexi.graphics.Font; +import org.vexi.graphics.Picture; + +/** + * Amalgamates Box's visual properties for memory/runtime efficiency: + * - text properties font, fontsize, text, textcolor + * - fill properties texture, fillcolor + **/ +final class BoxVisual implements Constants { + + //////// INSTANCE PROPERTIES ///////////////////////////////////// + + private short flags = 0; + int fontsize = 0; + int fillcolor = DEFAULT_FILLCOLOR; + int textcolor = DEFAULT_COLOR; + short textwidth = 0; + short textheight = 0; + Font font = DEFAULT_FONT; + JSString text = EMPTY_STRING; + Picture texture = null; + + + //////// CONSTRUCTORS ///////////////////////////////////////////// + + /** construct default text */ + BoxVisual() { } + + /** construct new text object based on font from 'stream' of size 'pointsize' */ + BoxVisual(JS stream) { + set(FONTSTREAM_SET); + setFont(stream, MEDIUM_SIZE); + } + + /** construct new text object based on font from 'stream' of size 'pointsize' */ + BoxVisual(int pointsize) { + set(FONTSIZE_SET); + setFont(DEFAULT_STREAM, pointsize); + } + + + //////// STATIC CONTENT /////////////////////////////////////////// + + private static final short FILLCOLOR_SET = 0x0001; + private static final short FONTCOLOR_SET = 0x0002; + private static final short FONTSIZE_SET = 0x0004; + private static final short FONTSTREAM_SET = 0x0008; + + private static final short FONT_TRAP = 0x0010; + private static final short FONTSIZE_TRAP = 0x0020; + + static int XXSMALL_OFFSET = -8; + static int XSMALL_OFFSET = -4; + static int SMALL_OFFSET = -2; + static int MEDIUM_SIZE = 10; + static int LARGE_OFFSET = 4; + static int XLARGE_OFFSET = 8; + static int XXLARGE_OFFSET = 14; + + static int DEFAULT_COLOR = 0xFF000000; + static int DEFAULT_FILLCOLOR = 0x00000000; + static Fountain DEFAULT_STREAM = Main.vera; + static Font DEFAULT_FONT = Font.getFont(DEFAULT_STREAM, MEDIUM_SIZE); + static BoxVisual DEFAULT = new BoxVisual(); + static JSString EMPTY_STRING = (JSString) JSU.S("", true); + + static int getDefaultFontSize() { return MEDIUM_SIZE; } + static Fountain getDefaultStream() { return DEFAULT_STREAM; } + static Font getDefaultFont() { return DEFAULT_FONT; } + + /** access for controlling default pointsize */ + static boolean setDefaultPointsize(int pointsize) { + if (pointsize == MEDIUM_SIZE) { + return false; + } + MEDIUM_SIZE = pointsize; + DEFAULT_FONT = Font.getFont(DEFAULT_STREAM, MEDIUM_SIZE); + return true; + } + + /** access for controlling default stream */ + static boolean setDefaultStream(Fountain stream) { + if (stream == DEFAULT_STREAM) { + return false; + } + DEFAULT_STREAM = stream; + DEFAULT_FONT = Font.getFont(DEFAULT_STREAM, MEDIUM_SIZE); + return true; + } + + /** return appropriate JS constant for size */ + static JS sizeToJS(int pointsize) { + switch (pointsize) { + case -3: return SC_xxsmall; + case -2: return SC_xsmall; + case -1: return SC_small; + case 0: return SC_medium; + case 1: return SC_large; + case 2: return SC_xlarge; + case 3: return SC_xxlarge; + default: return JSU.N(pointsize); + } + } + + /** convert size represented in JS to appropriate pointsize */ + static int jsToPointsize(JS size) throws JSExn { + return normalizeSize(jsToSize(size)); + } + + /** convert size represented in JS to appropriate integer value */ + static int jsToSize(JS size) throws JSExn { + if (size==null) { + return MEDIUM_SIZE; + } + if (size.type()==SC_number) { + int ps = JSU.toInt(size); + if (ps<6) { + throw new JSExn("Minimum fontsize is 6 - set to null or 'medium' for default size"); + } + return ps; + } else { + if (size.type()!=SC_string) { + throw new JSExn("type not applicable for fontsize: '"+size.type()+"'"); + } + } + String sizeStr = JSU.toString(size); + try { + switch (sizeStr.charAt(0)) { + case 'm': + if (sizeStr.equals("medium")) { + return 0; + } + case 's': + if (sizeStr.equals("small")) { + return -1; + } + case 'l': + if (sizeStr.equals("large")) { + return 1; + } + case 'x': + if (sizeStr.charAt(1) == 'x') { + if (sizeStr.equals("xxsmall")) {// || sizeStr.equals("xx-small")) { + return -3; + } + if (sizeStr.equals("xxlarge")) {// || sizeStr.equals("xx-large")) { + return 3; + } + } else { + if (sizeStr.equals("xsmall")) {// || sizeStr.equals("x-small")) { + return -2; + } + if (sizeStr.equals("xlarge")) {// || sizeStr.equals("x-large")) { + return 2; + } + } + default: + return Integer.parseInt(sizeStr, 10); + } + } catch (Exception e) { + throw new JSExn("illegal fontsize: "+sizeStr+""); + } + } + + /** check/convert offset pointsize to literal pointsize */ + static final int normalizeSize(int pointsize) { + if (pointsize>5) { + return pointsize; + } + int ps = MEDIUM_SIZE; + switch (pointsize) { + case -3: ps += XXSMALL_OFFSET; break; + case -2: ps += XSMALL_OFFSET; break; + case -1: ps += SMALL_OFFSET; break; + case 0: break; + case 1: ps += LARGE_OFFSET; break; + case 2: ps += XLARGE_OFFSET; break; + case 3: ps += XXLARGE_OFFSET; break; + } + return ps>5 ? ps : 6; + } + + + //////// HELPER FUNCTIONS ///////////////////////////////////////// + + // FLAGS helper functions + private final void set(short mask) { flags |= mask; } + private final void clear(short mask) { flags &= ~mask; } + private final boolean test(short mask) { return ((flags & mask) == mask); } + + boolean activeTrapFontsize() { return test(FONTSIZE_TRAP); } + void clearTrapFont() { clear(FONT_TRAP); } + void clearTrapFontsize() { clear(FONTSIZE_TRAP); } + void setTrapFont(Box box) { + if (this == DEFAULT) { + BoxVisual t = new BoxVisual(); + t.set(FONT_TRAP); + box.visual = t; + } else { + set(FONT_TRAP); + } + } + void setTrapFontsize(Box box) { + if (this == DEFAULT) { + BoxVisual t = new BoxVisual(); + t.set(FONTSIZE_TRAP); + box.visual = t; + } else { + set(FONTSIZE_TRAP); + } + } + + private final void setFont(JS stream, int pointsize) { + if (stream == font.stream && pointsize == this.fontsize) { + return; + } + font = Font.getFont(stream, normalizeSize(pointsize)); + this.fontsize = pointsize; + calculateDimensions(); + } + + + //////// INSTANCE FUNCTIONS /////////////////////////////////////// + + boolean isEmpty() { return text == EMPTY_STRING; } + boolean isDefaultSize() { return !test(FONTSIZE_SET); } + boolean isDefaultColor() { return !test(FONTCOLOR_SET); } + boolean isDefaultStream() { return !test(FONTSTREAM_SET); } + + /** set textcolor to default color + * @return boolean stating if textcolor has changed */ + boolean resetTextcolor() { + if (this != DEFAULT && test(FONTCOLOR_SET)) { + textcolor = DEFAULT_COLOR; + clear(FONTCOLOR_SET); + return true; + } + return false; + } + + /** set textcolor using arbitrary string, converting as necessary + * @return boolean stating if textcolor has changed */ + boolean setTextcolor(JS jstextcolor, Box box) throws JSExn { + int c = Color.stringToColor(JSU.toString(jstextcolor)); + return setTextcolor(c, box); + } + + /** set textcolor to integer value + * @return boolean stating if textcolor has changed */ + boolean setTextcolor(int textcolor, Box box) { + if (test(FONTCOLOR_SET) && textcolor == this.textcolor) { + return false; + } + if (this == DEFAULT) { + BoxVisual t = new BoxVisual(); + t.set(FONTCOLOR_SET); + t.textcolor = textcolor; + box.visual = t; + } else { + set(FONTCOLOR_SET); + this.textcolor = textcolor; + } + return true; + } + + /** set fillcolor to arbitrary value */ + private boolean setFillcolor(int fillcolor, Box box) { + if (test(FILLCOLOR_SET) && fillcolor == this.fillcolor) { + return false; + } + if (this == DEFAULT) { + BoxVisual t = new BoxVisual(); + t.fillcolor = fillcolor; + t.set(FILLCOLOR_SET); + box.visual = t; + } else { + set(FILLCOLOR_SET); + this.fillcolor = fillcolor; + if (texture != null) { + texture = null; + } + } + return true; + } + + private boolean setTexture(Picture texture, Box box) { + if (texture == this.texture) { + return false; + } + if (this == DEFAULT) { + BoxVisual t = new BoxVisual(); + t.texture = texture; + box.visual = t; + } else { + this.texture = texture; + // set fillcolor to be transparent + fillcolor = DEFAULT_FILLCOLOR; + clear(FILLCOLOR_SET); + } + return true; + } + + /** set the fill of a box according to 'value', converting as necessary */ + boolean setFill(JS value, Box box) throws JSExn { + if (value == null) { + return resetFill(); + } else if (JSU.isString(value)) { + // use as a hex colour value + int newfillcolor = Color.stringToColor(JSU.toString(value)); + return setFillcolor(newfillcolor, box); + } else { + // stream fill - load texture + Picture newtex = Picture.load(value, box); + // REMARK - Box.run() depends on visual + // so we need to call setTexture() before it + boolean textureChanged = setTexture(newtex, box); + if (textureChanged && newtex.isLoaded) { + box.run(null); + } + return textureChanged; + } + } + + /** set fillcolor to default fillcolor */ + boolean resetFill() { + if (texture==null && !test(FILLCOLOR_SET)) { + return false; + } + // set fillcolor to be transparent + fillcolor = DEFAULT_FILLCOLOR; + clear(FILLCOLOR_SET); + texture = null; + return true; + } + + /** set pointsize of this text object */ + boolean resetFontsize() { + if (test(FONTSIZE_SET) && this != DEFAULT) { + if (fontsize != MEDIUM_SIZE) { + setFont(font.stream, MEDIUM_SIZE); + } + clear(FONTSIZE_SET); + return true; + } + return false; + } + + /** set pointsize to arbitary value */ + boolean setFontsize(JS jsfontsize, Box box) throws JSExn { + int ps = jsToSize(jsfontsize); + return setFontsize(ps, box); + } + boolean setFontsize(int fontsize, Box box) { + if (test(FONTSIZE_SET) && fontsize == this.fontsize) { + return false; + } + if (this == DEFAULT) { + box.visual = new BoxVisual(fontsize); + } else { + set(FONTSIZE_SET); + if (fontsize<6 || fontsize != this.fontsize) { + setFont(font.stream, fontsize); + } + } + return true; + } + + /** set font stream of this text object */ + boolean resetStream() { + if (this != DEFAULT && test(FONTSTREAM_SET)) { + if (font.stream != DEFAULT_STREAM) { + setFont(DEFAULT_STREAM, fontsize); + } + clear(FONTSTREAM_SET); + return true; + } + return false; + } + + /** set stream to arbitrary font stream */ + boolean setStream(JS stream, Box box) { + if (test(FONTSTREAM_SET) && stream == font.stream) { + return false; + } + if (this == DEFAULT) { + box.visual = new BoxVisual(stream); + } else { + set(FONTSTREAM_SET); + setFont(stream, fontsize); + } + return true; + } + + /** set string representing text object */ + //void resetString() { return setString(EMPTY_STRING); } + boolean setString(JSString text, Box box) { + if (text==null) { + text = EMPTY_STRING; + } + if (text.equals(this.text)) { + return false; + } + if (this == DEFAULT) { + BoxVisual t = new BoxVisual(); + box.visual = t; + t.text = text; + t.calculateDimensions(); + } else { + this.text = text; + calculateDimensions(); + } + return true; + } + + /** establish dimensions of rendered text contents */ + private void calculateDimensions() { + if (text == EMPTY_STRING) { + textwidth = 0; + textheight = 0; + return; + } + long textsize = font.textsize(text.toString()); + int iwidth = (int)((textsize >>> 32) & 0xffffffff); + int iheight = (int)(textsize & 0xffffffffL); + textwidth = iwidth > Short.MAX_VALUE ? Short.MAX_VALUE : (short)iwidth; + textheight = iheight > Short.MAX_VALUE ? Short.MAX_VALUE : (short)iheight; + } +} Modified: branches/vexi3/org.vexi-core.main/src/main/jpp/org/vexi/core/Box.jpp =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/jpp/org/vexi/core/Box.jpp 2013-11-20 15:47:48 UTC (rev 4583) +++ branches/vexi3/org.vexi-core.main/src/main/jpp/org/vexi/core/Box.jpp 2013-11-20 17:46:52 UTC (rev 4584) @@ -220,7 +220,7 @@ private final boolean test(int mask) { return ((flags & mask) == mask); } public final int getIntFillcolor() { - return renderprops.fillcolor; + return visual.fillcolor; } /** for Surface to set the x/y properties of the root box */ @@ -331,7 +331,7 @@ private short trapflags = 0; private BasicTree bt = null; // rendering properties - BoxRenderProperties renderprops = BoxRenderProperties.DEFAULT_RENDER_PROPS; + BoxVisual visual = BoxVisual.DEFAULT; // FEATURE: path support //private Path path = null; @@ -356,7 +356,7 @@ protected int y = 0; public int width = 0; public int height = 0; - protected int contentwidth = 0; // == min(maxwidth, max(minwidth, renderprops.textwidth, sum(child.contentwidth))) + protected int contentwidth = 0; // == min(maxwidth, max(minwidth, visual.textwidth, sum(child.contentwidth))) protected int contentheight = 0; @@ -373,7 +373,7 @@ return; } // get around sub-sampling of enlarged textures - if (cur.renderprops.texture != null && !cur.test(TILE_IMAGE)) { + if (cur.visual.texture != null && !cur.test(TILE_IMAGE)) { // REMARK: inefficient but otherwise the consistency of // translating enlarged pixels to on-screen coordinates // can not be guaranteed as it depends upon first @@ -410,23 +410,23 @@ /** invoked when a resource needed to render ourselves finishes loading */ public Object run(Object o) throws JSExn { - if (renderprops.texture == null) { + if (visual.texture == null) { // Pictures are loaded asynchronously, then the Box is scheduled. // It is possible that the texture has been removed inbetween, // not an error though it may indicate bad Vexi code. Log.system.debug(Box.class, "Called run() on a Box with a null texture"); - } else if (renderprops.texture.isLoaded) { + } else if (visual.texture.isLoaded) { dirty(); // Tiled images affect contentsize if (test(TILE_IMAGE)) { - setMinWidth(renderprops.texture.width, true); - setMinHeight(renderprops.texture.height, true); + setMinWidth(visual.texture.width, true); + setMinHeight(visual.texture.height, true); setConstrain(); } - } else if (renderprops.texture.loadFailed!=null) { - //JS res = renderprops.texture.stream; - justTriggerTraps(SC_fill, renderprops.texture.loadFailed.asObject()); - renderprops.resetFill(); + } else if (visual.texture.loadFailed!=null) { + //JS res = visual.texture.stream; + justTriggerTraps(SC_fill, visual.texture.loadFailed.asObject()); + visual.resetFill(); // just in case of previous image / fill dirty(); // Tiled images affect contentsize @@ -541,15 +541,15 @@ static protected final void reflowTreeTextSize(Box box) throws JSExn { box.set(CONSTRAIN_DESCENDENT); box.set(PLACE_DESCENDENT); - if (box.renderprops.fontsize<6) { - if (box.renderprops!=BoxRenderProperties.DEFAULT_RENDER_PROPS) { - box.renderprops.resetFontsize(); + if (box.visual.fontsize<6) { + if (box.visual!=BoxVisual.DEFAULT) { + box.visual.resetFontsize(); } - if (box.renderprops.textwidth!=0) { + if (box.visual.textwidth!=0) { box.set(CONSTRAIN); box.set(PLACE); } - box.justTriggerTraps(SC_fontsize, BoxRenderProperties.sizeToJS(box.renderprops.fontsize)); + box.justTriggerTraps(SC_fontsize, BoxVisual.sizeToJS(box.visual.fontsize)); } int i=0; for (Box b = box.getChild(i); b!=null; b=box.getChild(++i)) { @@ -658,13 +658,13 @@ clear(HAS_WIDTH_SLACK); } } else { - if (new_contentwidth < maxwidth && (new_contentwidth < minwidth || new_contentwidth < renderprops.textwidth || - (renderprops.texture!=null && new_contentwidth < renderprops.texture.width))) { + if (new_contentwidth < maxwidth && (new_contentwidth < minwidth || new_contentwidth < visual.textwidth || + (visual.texture!=null && new_contentwidth < visual.texture.width))) { set(HAS_WIDTH_SLACK); } else { clear(HAS_WIDTH_SLACK); } - new_contentwidth = max(new_contentwidth, renderprops.textwidth); + new_contentwidth = max(new_contentwidth, visual.textwidth); } new_contentwidth = min(maxwidth, max(minwidth, new_contentwidth)); @@ -719,7 +719,7 @@ // place children individually in box space if (!test(PACK)) { - for (Box child = getChild(i=0); child != null; child = getChild(++i)) { + for (Box child = getChild(i=treeSize()-1); child != null; child = getChild(--i)) { if (!child.test(DISPLAY)) { continue; } @@ -1031,19 +1031,19 @@ if (parent == null) { // disregard transparency for root - buf.fillTrapezoid(cx1, cx2, cy1, cx1, cx2, cy2, renderprops.fillcolor|0xFF000000); - } else if ((renderprops.fillcolor & 0xFF000000) != 0x00000000) { + buf.fillTrapezoid(cx1, cx2, cy1, cx1, cx2, cy2, visual.fillcolor|0xFF000000); + } else if ((visual.fillcolor & 0xFF000000) != 0x00000000) { // normal color fill, skipping fully transparent fills - buf.fillTrapezoid(cx1, cx2, cy1, cx1, cx2, cy2, renderprops.fillcolor); + buf.fillTrapezoid(cx1, cx2, cy1, cx1, cx2, cy2, visual.fillcolor); } - if (renderprops.texture != null && renderprops.texture.isLoaded) { - int tw = renderprops.texture.width; - int th = renderprops.texture.height; + if (visual.texture != null && visual.texture.isLoaded) { + int tw = visual.texture.width; + int th = visual.texture.height; if (test(TILE_IMAGE)) { for (int x = globalx; x < cx2; x += tw) { for (int y = globaly; y < cy2; y += th) { - buf.drawPicture(renderprops.texture, x, y, cx1, cy1, cx2, cy2); + buf.drawPicture(visual.texture, x, y, cx1, cy1, cx2, cy2); } } } else { @@ -1051,18 +1051,18 @@ int sy1 = (int)(th * ((float)(cy1-globaly)/height) + 0.5); int sx2 = (int)(tw * ((float)(cx2-globalx)/width) + 0.5); int sy2 = (int)(th * ((float)(cy2-globaly)/height) + 0.5); - buf.drawPicture(renderprops.texture, cx1, cy1, cx2, cy2, sx1, sy1, sx2, sy2); + buf.drawPicture(visual.texture, cx1, cy1, cx2, cy2, sx1, sy1, sx2, sy2); } } - // REMARK: renderprops.font may still be null at this point so - // cannot use renderprops.isEmpty() but instead use renderprops.textwidth - if (renderprops.textwidth != 0) { - int gap_x = width - renderprops.textwidth; - int gap_y = height - renderprops.textheight; + // REMARK: visual.font may still be null at this point so + // cannot use visual.isEmpty() but instead use visual.textwidth + if (visual.textwidth != 0) { + int gap_x = width - visual.textwidth; + int gap_y = height - visual.textheight; int text_x = globalx + (test(ALIGN_RIGHT) ? gap_x : !test(ALIGN_LEFT) ? gap_x/2 : 0); int text_y = globaly + (test(ALIGN_BOTTOM) ? gap_y : !test(ALIGN_TOP) ? gap_y/2 : 0); - renderprops.font.rasterizeGlyphs(renderprops.text.toString(), buf, renderprops.textcolor, text_x, text_y, cx1, cy1, cx2, cy2); + visual.font.rasterizeGlyphs(visual.text.toString(), buf, visual.textcolor, text_x, text_y, cx1, cy1, cx2, cy2); } //if (path != null) path.realize(Affine.translate(globalx, globaly)).stroke(buf, 1, strokecolor); @@ -1652,7 +1652,7 @@ // FIXME: another hack // we really should return a re-usable JS stream Box b = new Box(); - BoxRenderProperties r = b.renderprops = new BoxRenderProperties(); + BoxVisual r = b.visual = new BoxVisual(); r.texture = pb.toPicture(); return b; } @@ -1782,7 +1782,7 @@ case "path": if (path != null) return JSU.S(path.toString()); String ret = ""; - for(int i=0; i<renderprops.str.length(); i++) ret += font.glyphs[renderprops.str.charAt(i)].path; + for(int i=0; i<visual.str.length(); i++) ret += font.glyphs[visual.str.charAt(i)].path; return JSU.S(ret); case "strokecolor": return JSU.S(Color.colorToString(strokecolor)); case "strokewidth": return JSU.N(strokewidth); @@ -1820,10 +1820,10 @@ * @type(String<br/>Stream) * */ case "fill": - if (renderprops.texture == null) { - return JSU.S(Color.colorToString(renderprops.fillcolor)); + if (visual.texture == null) { + return JSU.S(Color.colorToString(visual.fillcolor)); } - return renderprops.texture.stream; + return visual.texture.stream; /* <p>When an object is written to this property, its stream is read using the * <a href="http://www.freetype.org/" target="_top">freetype2 library</a>, and the @@ -1833,7 +1833,7 @@ * @initial_value(vexi.ui.font.vera) * @nofollow * */ - case "font": return renderprops.font.stream; + case "font": return visual.font.stream; /* <p>The size, either in points or relative size, to render the text.</p> * @@ -1854,7 +1854,7 @@ * @type(Number) * @initial_value("medium") * */ - case "fontsize": return BoxRenderProperties.sizeToJS(renderprops.fontsize); + case "fontsize": return BoxVisual.sizeToJS(visual.fontsize); /* <p>The text of a box. Visually <code>null</code> renders the same as the text to "" * (i.e as nothing).</p> @@ -1863,7 +1863,7 @@ * @type(String) * @nofollow * */ - case "text": return renderprops.text; + case "text": return visual.text; /* <p>If the value is a 5-character hex string (#RGB), 7-character hex string (#RRGGBB), * 9-character hex string (#AARRGGBB), a box's text color will be set to that color.</p> @@ -1877,7 +1877,7 @@ * @initial_value("#ffffff") * @type(String) * */ - case "textcolor": return JSU.S(Color.colorToString(renderprops.textcolor)); + case "textcolor": return JSU.S(Color.colorToString(visual.textcolor)); /* <p>This property can be set to any of the values specified for textcolor. If the value * written is a stream then it will interpreted as a PNG, GIF, or JPEG image, which will @@ -2443,52 +2443,52 @@ throw new JSExn("Attempt to put a non-stream to the 'font' property of a box"); } if (value == null) { - if (!renderprops.resetStream()) { + if (!visual.resetStream()) { return; } } else { Fountain fontstream = (Fountain)value.unclone(); - if (!renderprops.setStream(fontstream, this)) { + if (!visual.setStream(fontstream, this)) { return; } } - if (!renderprops.isEmpty()) { + if (!visual.isEmpty()) { setConstrain(); dirty(); } case "fontsize": if (value==null) { - if (!renderprops.resetFontsize()) { + if (!visual.resetFontsize()) { return; } } else { - if (!renderprops.setFontsize(value, this)) { + if (!visual.setFontsize(value, this)) { return; } } - if (!renderprops.isEmpty()) { + if (!visual.isEmpty()) { setConstrain(); dirty(); } case "text": JSString s = value == null ? null : value instanceof JSString ? (JSString)value : (JSString)JSU.S(JSU.toString(value)); - if (renderprops.setString(s, this)) { + if (visual.setString(s, this)) { setConstrain(); dirty(); } case "textcolor": try { if (value==null) { - if (!renderprops.resetTextcolor()) { + if (!visual.resetTextcolor()) { return; } } else { - if (!renderprops.setTextcolor(value, this)) { + if (!visual.setTextcolor(value, this)) { return; } } - if (!renderprops.isEmpty()) { + if (!visual.isEmpty()) { dirty(); } } catch (ClassCastException cce) { @@ -2595,16 +2595,16 @@ } case "align": setAlign(value); case "fill": - if (value == null && renderprops.texture != null && test(TILE_IMAGE)) { + if (value == null && visual.texture != null && test(TILE_IMAGE)) { setConstrain(); } - if (renderprops.setFill(value, this)) { + if (visual.setFill(value, this)) { dirty(); } case "tile": if (CHECKSET_FLAG(TILE_IMAGE)) { dirty(); - if (renderprops.texture != null && renderprops.texture.isLoaded) { + if (visual.texture != null && visual.texture.isLoaded) { if (test(TILE_IMAGE)) { // this will cause the Box's minimum dimensions // to be set to the image dimensions when tiled @@ -2913,8 +2913,8 @@ case "_Move": set(_MOVE_TRAP); case "Move": set(MOVE_TRAP); case "Resize": set(RESIZE_TRAP); - case "fontsize": renderprops.setTrapFontsize(this); - case "font": renderprops.setTrapFont(this); + case "fontsize": visual.setTrapFontsize(this); + case "font": visual.setTrapFont(this); case "shrink": set(SHRINK_TRAP); case "hshrink": set(HSHRINK_TRAP); case "vshrink": set(VSHRINK_TRAP); @@ -2954,8 +2954,8 @@ case "_Move": if (wtrap(SC__Move) == null) clear(_MOVE_TRAP); case "Move": if (wtrap(SC_Move) == null) clear(MOVE_TRAP); case "Resize": if (wtrap(SC_Resize) == null) clear(RESIZE_TRAP); - case "fontsize": if (wtrap(SC_fontsize) == null && renderprops != BoxRenderProperties.DEFAULT_RENDER_PROPS) renderprops.clearTrapFontsize(); - case "font": if (wtrap(SC_font) == null && renderprops != BoxRenderProperties.DEFAULT_RENDER_PROPS) renderprops.clearTrapFont(); + case "fontsize": if (wtrap(SC_fontsize) == null && visual != BoxVisual.DEFAULT) visual.clearTrapFontsize(); + case "font": if (wtrap(SC_font) == null && visual != BoxVisual.DEFAULT) visual.clearTrapFont(); case "shrink": if (wtrap(SC_shrink) == null) clear(SHRINK_TRAP); case "hshrink": if (wtrap(SC_hshrink) == null) clear(HSHRINK_TRAP); case "vshrink": if (wtrap(SC_vshrink) == null) clear(VSHRINK_TRAP); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Shape the Mobile Experience: Free Subscription Software experts and developers: Be at the forefront of tech innovation. Intel(R) Software Adrenaline delivers strategic insight and game-changing conversations that shape the rapidly evolving mobile landscape. Sign up now. http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn