com.adobe.fontengine.font.cff.FdSelect Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*
*
* File: FdSelect.java
*
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2004-2005 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property of
* Adobe Systems Incorporated and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe Systems
* Incorporated and its suppliers and may be covered by U.S. and Foreign
* Patents, patents in process, and are protected by trade secret or
* copyright law. Dissemination of this information or reproduction of this
* material is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*
*/
package com.adobe.fontengine.font.cff;
import com.adobe.fontengine.font.InvalidFontException;
import com.adobe.fontengine.font.Subset;
import com.adobe.fontengine.font.cff.CFFByteArray.CFFByteArrayBuilder;
/** Represents an FDSelect.
*/
final class FdSelect {
/* Our strategy is to just keep our thumb on the underlying bytes,
* and to interpret them when needed. */
/** The container for our bytes. */
protected final CFFByteArray data;
/** The offset of our bytes in data
. */
protected final int offset;
/** The number of bytes for our data, starting at offset
. */
protected final int size;
/** Construct a FDSelect
from a CFFByteArray
.
* @param data the CFFByteArray to get data from
* @param offset the offset of the first byte in data
* @param numGlyphs the number of glyphs in this font.
*/
public FdSelect (CFFByteArray data, int offset, int numGlyphs) throws InvalidFontException {
this.data = data;
this.offset = offset;
this.size = size (numGlyphs);
}
/** Return a trivial FdSelect for a a single font with numGlyphs
. */
public static FdSelect singleFont (int numGlyphs) throws InvalidFontException {
CFFByteArrayBuilder bb = CFFByteArray.getCFFByteArrayBuilderInstance(8);
bb.addCard8 (3); // format
bb.addCard16 (1); // nb of ranges
bb.addCard16 (0); // first gid
bb.addCard8 (0); // component 0
bb.addCard16 (numGlyphs); // sentinel GID
return new FdSelect (bb.toCFFByteArray(), 0, numGlyphs);
}
private static FdSelect format0Generator(FdSelect origSelect, Subset subset)
throws InvalidFontException {
CFFByteArrayBuilder bb = CFFByteArray.getCFFByteArrayBuilderInstance(1 + subset.getNumGlyphs());
bb.addCard8(0);
for (int i = 0; i < subset.getNumGlyphs(); i++) {
bb.addCard8(origSelect.componentOf(subset.getFullGid(i))); }
return new FdSelect(bb.toCFFByteArray(), 0, subset.getNumGlyphs());
}
private static FdSelect format3Generator(FdSelect origSelect, Subset subset, int numRanges)
throws InvalidFontException {
CFFByteArrayBuilder bb = CFFByteArray.getCFFByteArrayBuilderInstance(5 + numRanges * 3);
int fd = origSelect.componentOf(subset.getFullGid(0));
bb.addCard8(3);
bb.addCard16(numRanges);
bb.addCard16(0);
for (int i = 1; i < subset.getNumGlyphs(); i++) {
int nextFD = origSelect.componentOf(subset.getFullGid(i));
if (fd != nextFD) {
bb.addCard8(fd);
bb.addCard16(i);
fd = nextFD; } }
bb.addCard8(fd);
bb.addCard16(subset.getNumGlyphs());
return new FdSelect(bb.toCFFByteArray(), 0, subset.getNumGlyphs());
}
public static FdSelect fdSelectFromSubset(FdSelect origSelect, Subset subset)
throws InvalidFontException {
int fd = origSelect.componentOf(subset.getFullGid(0));
int numRanges = 1;
for (int i = 1; i < subset.getNumGlyphs(); i++) {
int nextFD = origSelect.componentOf(subset.getFullGid(i));
if (fd != nextFD) {
numRanges++;
fd = nextFD; } }
int format0Size = subset.getNumGlyphs();
int format3Size = 4 + numRanges * 3;
if (format0Size <= format3Size) {
return format0Generator(origSelect, subset); }
return format3Generator(origSelect, subset, numRanges);
}
/** Return the index of the component font for a gid.
* The result is undefined if gid
is not
* a valid gid.
*
* @param gid the gid to lookup. The result is undefined if gid
* is not a valid gid.
* @return the index of component font for gid
*/
public int componentOf (int gid) throws InvalidFontException {
int o = offset;
int format = data.getcard8 (o);
o++;
switch (format) {
case 0: {
// in this format, we have an array indexed by gid, mapping
// to the target component font.
return data.getcard8 (o + gid); }
case 3: {
// in this format, we have a bunch of ranges of gids,
// each one mapping to the target component font for the gids
// in the range. The ranges are in increasing order, with the
// first range starting at gid 0; there is a sentinel which
// acts as a virtual range starting at numGlyphs
int nRanges = data.getcard16 (o);
o += 2;
int min = 0;
int max = nRanges - 1;
while (min <= max) {
// Invariant: if gid is in a range, then the index of
// that range in [min, max]
int s = (min + max) / 2;
int firstGid = data.getcard16 (o + 3*s);
int lastGid = data.getcard16 (o + 3*(s+1));
if (gid < firstGid) {
max = s - 1; }
else if (lastGid <= gid) {
min = s + 1; }
else {
return data.getcard8 (o + 3*s + 2); }}
throw new InvalidFontException ("invalid fdSelect at offset " + offset); }
default: {
throw new InvalidFontException ("invalid fdSelect format at " + offset); }}
}
/** Compute the size, in bytes, of this FdSelect. */
int size (int numGlyphs) throws InvalidFontException {
int o = offset;
int format = data.getcard8 (o);
o++;
switch (format) {
case 0: {
return 1 + numGlyphs; }
case 3: {
// in this format, we have a bunch of ranges of gids,
// each one mapping to the target component font for the gids
// in the range. The ranges are in increasing order, with the
// first range starting at gid 0; there is a sentinel which
// acts as a virtual range starting at numGlyphs
int nRanges = data.getcard16 (o);
return 1 /* format */ + 2 /* nRanges */ + 3 * nRanges + 2 /* sentinel */; }
default: {
throw new InvalidFontException ("invalid fdSelect format at " + offset); }}
}
/** Stream this charset at the end of a CFFByteArrayBuilder. */
public void stream (CFFByteArrayBuilder bb) throws InvalidFontException {
bb.addBytes (data, offset, size);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy