private void enqueueGlyphList(final SunGraphics2D sg2d, final GlyphList gl) { // assert rq.lock.isHeldByCurrentThread(); RenderBuffer buf = rq.getBuffer(); final int totalGlyphs = gl.getNumGlyphs(); int glyphBytesRequired = totalGlyphs * BYTES_PER_GLYPH_IMAGE; int posBytesRequired = gl.usePositions() ? totalGlyphs * BYTES_PER_GLYPH_POSITION : 0; int totalBytesRequired = 24 + glyphBytesRequired + posBytesRequired; final long[] images = gl.getImages(); final float glyphListOrigX = gl.getX() + 0.5f; final float glyphListOrigY = gl.getY() + 0.5f; // make sure the RenderQueue keeps a hard reference to the FontStrike // so that the associated glyph images are not disposed while enqueued rq.addReference(gl.getStrike()); if (totalBytesRequired <= buf.capacity()) { if (totalBytesRequired > buf.remaining()) { // process the queue first and then enqueue the glyphs rq.flushNow(); } rq.ensureAlignment(20); buf.putInt(DRAW_GLYPH_LIST); // enqueue parameters buf.putInt(totalGlyphs); buf.putInt(createPackedParams(sg2d, gl)); buf.putFloat(glyphListOrigX); buf.putFloat(glyphListOrigY); // now enqueue glyph information buf.put(images, 0, totalGlyphs); if (gl.usePositions()) { float[] positions = gl.getPositions(); buf.put(positions, 0, 2 * totalGlyphs); } } else { // queue is too small to accomodate glyphs; perform // the operation directly on the queue flushing thread rq.flushAndInvokeNow( new Runnable() { public void run() { drawGlyphList( totalGlyphs, gl.usePositions(), gl.isSubPixPos(), gl.isRGBOrder(), sg2d.lcdTextContrast, glyphListOrigX, glyphListOrigY, images, gl.getPositions()); } }); } }
/** * Packs the given parameters into a single int value in order to save space on the rendering * queue. Note that most of these parameters are only used for rendering LCD-optimized text, but * conditionalizing this work wouldn't make any impact on performance, so we will pack those * parameters even in the non-LCD case. */ private static int createPackedParams(SunGraphics2D sg2d, GlyphList gl) { return (((gl.usePositions() ? 1 : 0) << OFFSET_POSITIONS) | ((gl.isSubPixPos() ? 1 : 0) << OFFSET_SUBPIXPOS) | ((gl.isRGBOrder() ? 1 : 0) << OFFSET_RGBORDER) | ((sg2d.lcdTextContrast & 0xff) << OFFSET_CONTRAST)); }