1 /*
   2  * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.java2d.pipe;
  27 
  28 import java.awt.font.FontRenderContext;
  29 import java.awt.font.GlyphVector;
  30 import java.awt.font.TextLayout;
  31 
  32 import sun.java2d.SunGraphics2D;
  33 import sun.java2d.SurfaceData;
  34 import sun.font.GlyphList;
  35 import sun.java2d.loops.FontInfo;
  36 
  37 /**
  38  * A delegate pipe of SG2D for drawing text.
  39  */
  40 
  41 public abstract class GlyphListPipe implements TextPipe {
  42 
  43     public void drawString(SunGraphics2D sg2d, String s,
  44                            double x, double y)
  45     {
  46         FontInfo info = sg2d.getFontInfo();
  47         if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
  48             SurfaceData.outlineTextRenderer.drawString(sg2d, s, x, y);
  49             return;
  50         }
  51 
  52         float devx, devy;
  53         if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
  54             double[] origin = {x + info.originX, y + info.originY};
  55             sg2d.transform.transform(origin, 0, origin, 0, 1);
  56             devx = (float)origin[0];
  57             devy = (float)origin[1];
  58         } else {
  59             devx = (float)(x + info.originX + sg2d.transX);
  60             devy = (float)(y + info.originY + sg2d.transY);
  61         }
  62         /* setFromString returns false if shaping is needed, and we then back
  63          * off to a TextLayout. Such text may benefit slightly from a lower
  64          * overhead in this approach over the approach in previous releases.
  65          */
  66         GlyphList gl = GlyphList.getInstance();
  67         if (gl.setFromString(info, s, devx, devy)) {
  68             drawGlyphList(sg2d, gl);
  69             gl.dispose();
  70         } else {
  71             gl.dispose(); // release this asap.
  72             TextLayout tl = new TextLayout(s, sg2d.getFont(),
  73                                            sg2d.getFontRenderContext());
  74             tl.draw(sg2d, (float)x, (float)y);
  75         }
  76     }
  77 
  78     public void drawChars(SunGraphics2D sg2d,
  79                           char[] data, int offset, int length,
  80                           int ix, int iy)
  81     {
  82         FontInfo info = sg2d.getFontInfo();
  83         float x, y;
  84         if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
  85             SurfaceData.outlineTextRenderer.drawChars(
  86                                         sg2d, data, offset, length, ix, iy);
  87             return;
  88         }
  89         if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
  90             double[] origin = {ix + info.originX, iy + info.originY};
  91             sg2d.transform.transform(origin, 0, origin, 0, 1);
  92             x = (float) origin[0];
  93             y = (float) origin[1];
  94         } else {
  95             x = ix + info.originX + sg2d.transX;
  96             y = iy + info.originY + sg2d.transY;
  97         }
  98         GlyphList gl = GlyphList.getInstance();
  99         if (gl.setFromChars(info, data, offset, length, x, y)) {
 100             drawGlyphList(sg2d, gl);
 101             gl.dispose();
 102         } else {
 103             gl.dispose(); // release this asap.
 104             TextLayout tl = new TextLayout(new String(data, offset, length),
 105                                            sg2d.getFont(),
 106                                            sg2d.getFontRenderContext());
 107             tl.draw(sg2d, ix, iy);
 108 
 109         }
 110     }
 111 
 112     public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector gv,
 113                                 float x, float y)
 114     {
 115         FontRenderContext frc = gv.getFontRenderContext();
 116         FontInfo info = sg2d.getGVFontInfo(gv.getFont(), frc);
 117         if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
 118             SurfaceData.outlineTextRenderer.drawGlyphVector(sg2d, gv, x, y);
 119             return;
 120         }
 121         if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
 122             double[] origin = {x, y};
 123             sg2d.transform.transform(origin, 0, origin, 0, 1);
 124             x = (float) origin[0];
 125             y = (float) origin[1];
 126         } else {
 127             x += sg2d.transX; // don't use the glyph info origin, already in gv.
 128             y += sg2d.transY;
 129         }
 130 
 131         GlyphList gl = GlyphList.getInstance();
 132         gl.setFromGlyphVector(info, gv, x, y);
 133         drawGlyphList(sg2d, gl, info.aaHint);
 134         gl.dispose();
 135     }
 136 
 137     protected abstract void drawGlyphList(SunGraphics2D sg2d, GlyphList gl);
 138 
 139     protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl,
 140                                  int aaHint) {
 141         drawGlyphList(sg2d, gl);
 142     }
 143 }