예제 #1
0
 public PhysicalFont getSlotFont(int slot) {
   /* This is essentially the runtime overhead for deferred font
    * initialisation: a boolean test on obtaining a slot font,
    * which will happen per slot, on initialisation of a strike
    * (as that is the only frequent call site of this method.
    */
   if (deferredInitialisation[slot]) {
     doDeferredInitialisation(slot);
   }
   SunFontManager fm = SunFontManager.getInstance();
   try {
     PhysicalFont font = components[slot];
     if (font == null) {
       try {
         font =
             (PhysicalFont)
                 fm.findFont2D(componentNames[slot], style, FontManager.PHYSICAL_FALLBACK);
         components[slot] = font;
       } catch (ClassCastException cce) {
         font = fm.getDefaultPhysicalFont();
       }
     }
     return font;
   } catch (Exception e) {
     return fm.getDefaultPhysicalFont();
   }
 }
예제 #2
0
 PhysicalFont getDelegateFont() {
   if (delegateFont == null) {
     SunFontManager fm = SunFontManager.getInstance();
     delegateFont = fm.getDefaultPhysicalFont();
   }
   return delegateFont;
 }
예제 #3
0
 public CharToGlyphMapper getMapper() {
   if (mapper == null) {
     if (isBitmapDelegate) {
       /* we are a delegate */
       mapper = new NativeGlyphMapper(this);
     } else {
       /* we need to delegate */
       SunFontManager fm = SunFontManager.getInstance();
       delegateFont = fm.getDefaultPhysicalFont();
       mapper = delegateFont.getMapper();
     }
   }
   return mapper;
 }
예제 #4
0
 FontStrike createStrike(FontStrikeDesc desc) {
   if (isBitmapDelegate) {
     return new NativeStrike(this, desc);
   } else {
     if (delegateFont == null) {
       SunFontManager fm = SunFontManager.getInstance();
       delegateFont = fm.getDefaultPhysicalFont();
     }
     /* If no FileFont's are found, delegate font may be
      * a NativeFont, so we need to avoid recursing here.
      */
     if (delegateFont instanceof NativeFont) {
       return new NativeStrike((NativeFont) delegateFont, desc);
     }
     FontStrike delegate = delegateFont.createStrike(desc);
     return new DelegateStrike(this, desc, delegate);
   }
 }
예제 #5
0
  /* This is used for deferred initialisation, so that the components of
   * a logical font are initialised only when the font is used.
   * This can have a positive impact on start-up of most UI applications.
   * Note that this technique cannot be used with a TTC font as it
   * doesn't know which font in the collection is needed. The solution to
   * this is that the initialisation checks if the returned font is
   * really the one it wants by comparing the name against the name that
   * was passed in (if none was passed in then you aren't using a TTC
   * as you would have to specify the name in such a case).
   * Assuming there's only two or three fonts in a collection then it
   * may be sufficient to verify the returned name is the expected one.
   * But half the time it won't be. However since initialisation of the
   * TTC will initialise all its components then just do a findFont2D call
   * to locate the right one.
   * This code allows for initialisation of each slot on demand.
   * There are two issues with this.
   * 1) All metrics slots probably may be initialised anyway as many
   * apps will query the overall font metrics. However this is not an
   * absolute requirement
   * 2) Some font configuration files on Solaris reference two versions
   * of a TT font: a Latin-1 version, then a Pan-European version.
   * One from /usr/openwin/lib/X11/fonts/TrueType, the other from
   * a euro_fonts directory which is symlinked from numerous locations.
   * This is difficult to avoid because the two do not share XLFDs so
   * both will be consequently mapped by separate XLFDs needed by AWT.
   * The difficulty this presents for lazy initialisation is that if
   * all the components are not mapped at once, the smaller version may
   * have been used only to be replaced later, and what is the consequence
   * for a client that displayed the contents of this font already.
   * After some thought I think this will not be a problem because when
   * client tries to display a glyph only in the Euro font, the composite
   * will ask all components of this font for that glyph and will get
   * the euro one. Subsequent uses will all come from the 100% compatible
   * euro one.
   */
  private void doDeferredInitialisation(int slot) {
    if (deferredInitialisation[slot] == false) {
      return;
    }

    /* Synchronize on FontManager so that is the global lock
     * to update its static set of deferred fonts.
     * This global lock is rarely likely to be an issue as there
     * are only going to be a few calls into this code.
     */
    SunFontManager fm = SunFontManager.getInstance();
    synchronized (fm) {
      if (componentNames == null) {
        componentNames = new String[numSlots];
      }
      if (components[slot] == null) {
        /* Warning: it is possible that the returned component is
         * not derived from the file name argument, this can happen if:
         * - the file can't be found
         * - the file has a bad font
         * - the font in the file is superseded by a more complete one
         * This should not be a problem for composite font as it will
         * make no further use of this file, but code debuggers/
         * maintainers need to be conscious of this possibility.
         */
        if (componentFileNames != null && componentFileNames[slot] != null) {
          components[slot] = fm.initialiseDeferredFont(componentFileNames[slot]);
        }

        if (components[slot] == null) {
          components[slot] = fm.getDefaultPhysicalFont();
        }
        String name = components[slot].getFontName(null);
        if (componentNames[slot] == null) {
          componentNames[slot] = name;
        } else if (!componentNames[slot].equalsIgnoreCase(name)) {
          /* If a component specifies the file with a bad font,
           * the corresponding slot will be initialized by
           * default physical font. In such case findFont2D may
           * return composite font which cannot be casted to
           * physical font.
           */
          try {
            components[slot] =
                (PhysicalFont)
                    fm.findFont2D(componentNames[slot], style, FontManager.PHYSICAL_FALLBACK);
          } catch (ClassCastException cce) {
            /* Assign default physical font to the slot */
            components[slot] = fm.getDefaultPhysicalFont();
          }
        }
      }
      deferredInitialisation[slot] = false;
    }
  }
예제 #6
0
  public CompositeFont(
      String name,
      String[] compFileNames,
      String[] compNames,
      int metricsSlotCnt,
      int[] exclRanges,
      int[] maxIndexes,
      boolean defer,
      SunFontManager fm) {

    handle = new Font2DHandle(this);
    fullName = name;
    componentFileNames = compFileNames;
    componentNames = compNames;
    if (compNames == null) {
      numSlots = componentFileNames.length;
    } else {
      numSlots = componentNames.length;
    }
    /* We will limit the number of slots to 254.
     * We store the slot for a glyph id in a byte and we may use one slot
     * for an EUDC font, and we may also create a composite
     * using this composite as a backup for a physical font.
     * So we want to leave space for the two additional slots.
     */
    numSlots = (numSlots <= 254) ? numSlots : 254;

    /* Only the first "numMetricsSlots" slots are used for font metrics.
     * the rest are considered "fallback" slots".
     */
    numMetricsSlots = metricsSlotCnt;
    exclusionRanges = exclRanges;
    maxIndices = maxIndexes;

    /*
     * See if this is a windows locale which has a system EUDC font.
     * If so add it as the final fallback component of the composite.
     * The caller could be responsible for this, but for now it seems
     * better that it is handled internally to the CompositeFont class.
     */
    if (fm.getEUDCFont() != null) {
      numSlots++;
      if (componentNames != null) {
        componentNames = new String[numSlots];
        System.arraycopy(compNames, 0, componentNames, 0, numSlots - 1);
        componentNames[numSlots - 1] = fm.getEUDCFont().getFontName(null);
      }
      if (componentFileNames != null) {
        componentFileNames = new String[numSlots];
        System.arraycopy(compFileNames, 0, componentFileNames, 0, numSlots - 1);
      }
      components = new PhysicalFont[numSlots];
      components[numSlots - 1] = fm.getEUDCFont();
      deferredInitialisation = new boolean[numSlots];
      if (defer) {
        for (int i = 0; i < numSlots - 1; i++) {
          deferredInitialisation[i] = true;
        }
      }
    } else {
      components = new PhysicalFont[numSlots];
      deferredInitialisation = new boolean[numSlots];
      if (defer) {
        for (int i = 0; i < numSlots; i++) {
          deferredInitialisation[i] = true;
        }
      }
    }

    fontRank = Font2D.FONT_CONFIG_RANK;

    int index = fullName.indexOf('.');
    if (index > 0) {
      familyName = fullName.substring(0, index);
      /* composites don't call setStyle() as parsing the style
       * takes place at the same time as parsing the family name.
       * Do I really have to parse the style from the name?
       * Need to look into having the caller provide this. */
      if (index + 1 < fullName.length()) {
        String styleStr = fullName.substring(index + 1);
        if ("plain".equals(styleStr)) {
          style = Font.PLAIN;
        } else if ("bold".equals(styleStr)) {
          style = Font.BOLD;
        } else if ("italic".equals(styleStr)) {
          style = Font.ITALIC;
        } else if ("bolditalic".equals(styleStr)) {
          style = Font.BOLD | Font.ITALIC;
        }
      }
    } else {
      familyName = fullName;
    }
  }