src/share/classes/sun/font/GlyphLayout.java

Print this page


   1 /*
   2  * Copyright (c) 2003, 2008, 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


  75 import java.awt.geom.AffineTransform;
  76 import java.awt.geom.NoninvertibleTransformException;
  77 import java.awt.geom.Point2D;
  78 import java.util.ArrayList;
  79 import java.util.concurrent.ConcurrentHashMap;
  80 
  81 import static java.lang.Character.*;
  82 
  83 public final class GlyphLayout {
  84     // data for glyph vector
  85     private GVData _gvdata;
  86 
  87     // cached glyph layout data for reuse
  88     private static volatile GlyphLayout cache;  // reusable
  89 
  90     private LayoutEngineFactory _lef;  // set when get is called, unset when done is called
  91     private TextRecord _textRecord;    // the text we're working on, used by iterators
  92     private ScriptRun _scriptRuns;     // iterator over script runs
  93     private FontRunIterator _fontRuns; // iterator over physical fonts in a composite
  94     private int _ercount;
  95     private ArrayList _erecords;
  96     private Point2D.Float _pt;
  97     private FontStrikeDesc _sd;
  98     private float[] _mat;
  99     private int _typo_flags;
 100     private int _offset;
 101 
 102     public static final class LayoutEngineKey {
 103         private Font2D font;
 104         private int script;
 105         private int lang;
 106 
 107         LayoutEngineKey() {
 108         }
 109 
 110         LayoutEngineKey(Font2D font, int script, int lang) {
 111             init(font, script, lang);
 112         }
 113 
 114         void init(Font2D font, int script, int lang) {
 115             this.font = font;


 440                 int limit = _scriptRuns.getScriptLimit();
 441                 int script = _scriptRuns.getScriptCode();
 442                 nextEngineRecord(start, limit, script, lang, font2D, 0);
 443                 start = limit;
 444             }
 445         }
 446 
 447         int ix = 0;
 448         int stop = _ercount;
 449         int dir = 1;
 450 
 451         if (_typo_flags < 0) { // RTL
 452             ix = stop - 1;
 453             stop = -1;
 454             dir = -1;
 455         }
 456 
 457         //        _sd.init(dtx, gtx, font.getStyle(), frc.isAntiAliased(), frc.usesFractionalMetrics());
 458         _sd = txinfo.sd;
 459         for (;ix != stop; ix += dir) {
 460             EngineRecord er = (EngineRecord)_erecords.get(ix);
 461             for (;;) {
 462                 try {
 463                     er.layout();
 464                     break;
 465                 }
 466                 catch (IndexOutOfBoundsException e) {
 467                     if (_gvdata._count >=0) {
 468                         _gvdata.grow();
 469                     }
 470                 }
 471             }
 472             // Break out of the outer for loop if layout fails.
 473             if (_gvdata._count < 0) {
 474                 break;
 475             }
 476         }
 477 
 478         //        if (txinfo.invdtx != null) {
 479         //            _gvdata.adjustPositions(txinfo.invdtx);
 480         //        }


 488             if (FontUtilities.debugFonts()) {
 489                FontUtilities.getLogger().warning("OpenType layout failed on font: " +
 490                                                  font);
 491             }
 492         } else {
 493             gv = _gvdata.createGlyphVector(font, frc, result);
 494         }
 495         //        System.err.println("Layout returns: " + gv);
 496         return gv;
 497     }
 498 
 499     //
 500     // private methods
 501     //
 502 
 503     private GlyphLayout() {
 504         this._gvdata = new GVData();
 505         this._textRecord = new TextRecord();
 506         this._scriptRuns = new ScriptRun();
 507         this._fontRuns = new FontRunIterator();
 508         this._erecords = new ArrayList(10);
 509         this._pt = new Point2D.Float();
 510         this._sd = new FontStrikeDesc();
 511         this._mat = new float[4];
 512     }
 513 
 514     private void init(int capacity) {
 515         this._typo_flags = 0;
 516         this._ercount = 0;
 517         this._gvdata.init(capacity);
 518     }
 519 
 520     private void nextEngineRecord(int start, int limit, int script, int lang, Font2D font, int gmask) {
 521         EngineRecord er = null;
 522         if (_ercount == _erecords.size()) {
 523             er = new EngineRecord();
 524             _erecords.add(er);
 525         } else {
 526             er = (EngineRecord)_erecords.get(_ercount);
 527         }
 528         er.init(start, limit, font, script, lang, gmask);
 529         ++_ercount;
 530     }
 531 
 532     /**
 533      * Storage for layout to build glyph vector data, then generate a real GlyphVector
 534      */
 535     public static final class GVData {
 536         public int _count; // number of glyphs, >= number of chars
 537         public int _flags;
 538         public int[] _glyphs;
 539         public float[] _positions;
 540         public int[] _indices;
 541 
 542         private static final int UNINITIALIZED_FLAGS = -1;
 543 
 544         public void init(int size) {
 545             _count = 0;
 546             _flags = UNINITIALIZED_FLAGS;


   1 /*
   2  * Copyright (c) 2003, 2014, 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


  75 import java.awt.geom.AffineTransform;
  76 import java.awt.geom.NoninvertibleTransformException;
  77 import java.awt.geom.Point2D;
  78 import java.util.ArrayList;
  79 import java.util.concurrent.ConcurrentHashMap;
  80 
  81 import static java.lang.Character.*;
  82 
  83 public final class GlyphLayout {
  84     // data for glyph vector
  85     private GVData _gvdata;
  86 
  87     // cached glyph layout data for reuse
  88     private static volatile GlyphLayout cache;  // reusable
  89 
  90     private LayoutEngineFactory _lef;  // set when get is called, unset when done is called
  91     private TextRecord _textRecord;    // the text we're working on, used by iterators
  92     private ScriptRun _scriptRuns;     // iterator over script runs
  93     private FontRunIterator _fontRuns; // iterator over physical fonts in a composite
  94     private int _ercount;
  95     private ArrayList<EngineRecord> _erecords;
  96     private Point2D.Float _pt;
  97     private FontStrikeDesc _sd;
  98     private float[] _mat;
  99     private int _typo_flags;
 100     private int _offset;
 101 
 102     public static final class LayoutEngineKey {
 103         private Font2D font;
 104         private int script;
 105         private int lang;
 106 
 107         LayoutEngineKey() {
 108         }
 109 
 110         LayoutEngineKey(Font2D font, int script, int lang) {
 111             init(font, script, lang);
 112         }
 113 
 114         void init(Font2D font, int script, int lang) {
 115             this.font = font;


 440                 int limit = _scriptRuns.getScriptLimit();
 441                 int script = _scriptRuns.getScriptCode();
 442                 nextEngineRecord(start, limit, script, lang, font2D, 0);
 443                 start = limit;
 444             }
 445         }
 446 
 447         int ix = 0;
 448         int stop = _ercount;
 449         int dir = 1;
 450 
 451         if (_typo_flags < 0) { // RTL
 452             ix = stop - 1;
 453             stop = -1;
 454             dir = -1;
 455         }
 456 
 457         //        _sd.init(dtx, gtx, font.getStyle(), frc.isAntiAliased(), frc.usesFractionalMetrics());
 458         _sd = txinfo.sd;
 459         for (;ix != stop; ix += dir) {
 460             EngineRecord er = _erecords.get(ix);
 461             for (;;) {
 462                 try {
 463                     er.layout();
 464                     break;
 465                 }
 466                 catch (IndexOutOfBoundsException e) {
 467                     if (_gvdata._count >=0) {
 468                         _gvdata.grow();
 469                     }
 470                 }
 471             }
 472             // Break out of the outer for loop if layout fails.
 473             if (_gvdata._count < 0) {
 474                 break;
 475             }
 476         }
 477 
 478         //        if (txinfo.invdtx != null) {
 479         //            _gvdata.adjustPositions(txinfo.invdtx);
 480         //        }


 488             if (FontUtilities.debugFonts()) {
 489                FontUtilities.getLogger().warning("OpenType layout failed on font: " +
 490                                                  font);
 491             }
 492         } else {
 493             gv = _gvdata.createGlyphVector(font, frc, result);
 494         }
 495         //        System.err.println("Layout returns: " + gv);
 496         return gv;
 497     }
 498 
 499     //
 500     // private methods
 501     //
 502 
 503     private GlyphLayout() {
 504         this._gvdata = new GVData();
 505         this._textRecord = new TextRecord();
 506         this._scriptRuns = new ScriptRun();
 507         this._fontRuns = new FontRunIterator();
 508         this._erecords = new ArrayList<>(10);
 509         this._pt = new Point2D.Float();
 510         this._sd = new FontStrikeDesc();
 511         this._mat = new float[4];
 512     }
 513 
 514     private void init(int capacity) {
 515         this._typo_flags = 0;
 516         this._ercount = 0;
 517         this._gvdata.init(capacity);
 518     }
 519 
 520     private void nextEngineRecord(int start, int limit, int script, int lang, Font2D font, int gmask) {
 521         EngineRecord er = null;
 522         if (_ercount == _erecords.size()) {
 523             er = new EngineRecord();
 524             _erecords.add(er);
 525         } else {
 526             er = _erecords.get(_ercount);
 527         }
 528         er.init(start, limit, font, script, lang, gmask);
 529         ++_ercount;
 530     }
 531 
 532     /**
 533      * Storage for layout to build glyph vector data, then generate a real GlyphVector
 534      */
 535     public static final class GVData {
 536         public int _count; // number of glyphs, >= number of chars
 537         public int _flags;
 538         public int[] _glyphs;
 539         public float[] _positions;
 540         public int[] _indices;
 541 
 542         private static final int UNINITIALIZED_FLAGS = -1;
 543 
 544         public void init(int size) {
 545             _count = 0;
 546             _flags = UNINITIALIZED_FLAGS;