Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@

/**
* Display the page number and a page rendering.
*
*
* @author Tilman Hausherr
* @author John Hewson
*/
Expand Down Expand Up @@ -298,7 +298,7 @@ private void initUI()
pageLabel.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 20));
pageLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0));
panel.add(pageLabel);

label = new JLabel();
label.addMouseMotionListener(this);
label.addMouseListener(this);
Expand Down Expand Up @@ -395,7 +395,7 @@ public void ancestorAdded(AncestorEvent ancestorEvent)
{
zoomMenu.addMenuListeners(this);
zoomMenu.setEnableMenu(true);

rotationMenu = RotationMenu.getInstance();
rotationMenu.addMenuListeners(this);
rotationMenu.setEnableMenu(true);
Expand All @@ -412,7 +412,7 @@ public void ancestorAdded(AncestorEvent ancestorEvent)

JMenu menuInstance = viewMenu.getMenu();
int itemCount = menuInstance.getItemCount();

for (int i = 0; i< itemCount; i++)
{
JMenuItem item = menuInstance.getItem(i);
Expand All @@ -435,7 +435,7 @@ public void ancestorRemoved(AncestorEvent ancestorEvent)

JMenu menuInstance = viewMenu.getMenu();
int itemCount = menuInstance.getItemCount();

for (int i = 0; i< itemCount; i++)
{
JMenuItem item = menuInstance.getItem(i);
Expand Down Expand Up @@ -705,7 +705,7 @@ protected BufferedImage doInBackground() throws IOException

PDFRenderer renderer = new PDFRenderer(document);
renderer.setSubsamplingAllowed(ViewMenu.isAllowSubsampling());
//renderer.setHintingEnabled(ViewMenu.isHintingEnabled())
renderer.setHintingEnabled(ViewMenu.isHintingEnabled());

long t0 = System.nanoTime();
BufferedImage image = renderer.renderImage(pageIndex, scale, ImageTypeMenu.getImageType(), RenderDestinationMenu.getRenderDestination());
Expand All @@ -716,13 +716,13 @@ protected BufferedImage doInBackground() throws IOException
statuslabel.setText(labelText);

// debug overlays
DebugTextOverlay debugText = new DebugTextOverlay(document, pageIndex, scale,
DebugTextOverlay debugText = new DebugTextOverlay(document, pageIndex, scale,
showTextStripper, showTextStripperBeads,
showFontBBox, ViewMenu.isShowGlyphBounds());
Graphics2D g = image.createGraphics();
debugText.renderTo(g);
g.dispose();

return ImageUtil.getRotatedImage(image, rotation);
}

Expand All @@ -733,12 +733,12 @@ protected void done()
{
BufferedImage image = get();

// We cannot use "label.setIcon(new ImageIcon(get()))" here
// because of blurry upscaling in JDK9. Instead, the label is now created with
// We cannot use "label.setIcon(new ImageIcon(get()))" here
// because of blurry upscaling in JDK9. Instead, the label is now created with
// a smaller size than the image to compensate that the
// image is scaled up with some screen configurations (e.g. 125% on windows).
// See PDFBOX-3665 for more sample code and discussion.
label.setSize((int) Math.ceil(image.getWidth() / defaultTransform.getScaleX()),
label.setSize((int) Math.ceil(image.getWidth() / defaultTransform.getScaleX()),
(int) Math.ceil(image.getHeight() / defaultTransform.getScaleY()));
label.setIcon(new HighResolutionImageIcon(image, label.getWidth(), label.getHeight()));
label.setText(null);
Expand Down
140 changes: 140 additions & 0 deletions fontbox/src/main/java/org/apache/fontbox/ttf/BytecodeStream.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.fontbox.ttf;

/**
* A bounds-checked cursor over a TrueType bytecode program (fpgm, prep, a glyph instruction stream, or
* a function body). It owns the program counter so individual opcode handlers never index the array by
* hand - this removes a whole class of off-by-one and overrun bugs and is trivially testable on its
* own. Reads past the end throw {@link HintingException} so the per-glyph fallback can catch cleanly.
*
* @author Apache PDFBox
*/
class BytecodeStream
{
private final byte[] code;
private int ip;
private int instructionStart;

/**
* @param code the bytecode program; not copied
*/
public BytecodeStream(byte[] code)
{
this.code = code != null ? code : new byte[0];
}

/**
* @return the underlying bytecode array (not copied); used to record function entry points
*/
public byte[] getCode()
{
return code;
}

/**
* @return true if there is at least one more byte to read
*/
public boolean hasNext()
{
return ip < code.length;
}

/**
* @return the current program-counter position
*/
public int position()
{
return ip;
}

/**
* Records the current position as the start of the instruction about to be read. Relative jumps
* ({@code JMPR}/{@code JROT}/{@code JROF}) are measured from here.
*/
public void markInstructionStart()
{
instructionStart = ip;
}

/**
* @return the position recorded by the most recent {@link #markInstructionStart()}
*/
public int instructionStart()
{
return instructionStart;
}

/**
* Moves the program counter to an absolute position.
*
* @param position the new position, within {@code [0, length]}
* @throws HintingException if the position is out of range
*/
public void seek(int position)
{
if (position < 0 || position > code.length)
{
throw new HintingException(
"bytecode seek out of range: " + position + " of " + code.length);
}
ip = position;
}

/**
* Advances the program counter by a relative amount (may be negative).
*
* @param delta the number of bytes to skip
* @throws HintingException if the result is out of range
*/
public void skip(int delta)
{
seek(ip + delta);
}

/**
* Reads the next byte as an unsigned 0-255 value (an opcode, or push operand).
*
* @return the next unsigned byte
* @throws HintingException if the stream is exhausted
*/
public int nextByte()
{
if (ip >= code.length)
{
throw new HintingException("bytecode read past end at " + ip);
}
return code[ip++] & 0xFF;
}

/**
* Reads the next two bytes as a signed big-endian 16-bit word.
*
* @return the next signed word
* @throws HintingException if fewer than two bytes remain
*/
public int nextWord()
{
if (ip + 1 >= code.length)
{
throw new HintingException("bytecode word read past end at " + ip);
}
int hi = code[ip++] & 0xFF;
int lo = code[ip++] & 0xFF;
return (short) ((hi << 8) | lo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.fontbox.ttf;

import java.io.IOException;

/**
* The 'prep' (Control Value Program, also known as the pre-program) table. It holds TrueType hinting
* bytecode that is executed whenever the point size or transform changes, to prepare the Control Value
* Table and graphics state for the new ppem. The bytecode is stored here as raw bytes and run by the
* interpreter.
*
* @author Apache PDFBox
*/
public class ControlValueProgramTable extends TTFTable
{
/**
* A tag that identifies this table type.
*/
public static final String TAG = "prep";

private byte[] program;

ControlValueProgramTable()
{
}

/**
* This will read the required data from the stream.
*
* @param ttf The font that is being read.
* @param data The stream to read the data from.
* @throws IOException If there is an error reading the data.
*/
@Override
void read(TrueTypeFont ttf, TTFDataStream data) throws IOException
{
program = data.read((int) getLength());
initialized = true;
}

/**
* Returns the raw control value program bytecode.
*
* @return the bytecode of the pre-program
*/
public byte[] getProgram()
{
return program;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.fontbox.ttf;

import java.io.IOException;

/**
* The 'cvt ' (Control Value) table. It holds an array of reference values - stem widths, heights and
* similar control measurements - used by the TrueType hinting bytecode. The values are stored here in
* raw font units (signed FWords); they are scaled to the active ppem by the interpreter, not at parse
* time.
*
* @author Apache PDFBox
*/
public class ControlValueTable extends TTFTable
{
/**
* A tag that identifies this table type.
*/
public static final String TAG = "cvt ";

private int[] values;

ControlValueTable()
{
}

/**
* This will read the required data from the stream.
*
* @param ttf The font that is being read.
* @param data The stream to read the data from.
* @throws IOException If there is an error reading the data.
*/
@Override
void read(TrueTypeFont ttf, TTFDataStream data) throws IOException
{
int count = (int) (getLength() / 2);
int[] cvt = new int[count];
for (int i = 0; i < count; i++)
{
cvt[i] = data.readSignedShort();
}
values = cvt;
initialized = true;
}

/**
* Returns the raw control values in font units (FWords). The interpreter scales these to the
* active ppem.
*
* @return the control values in font units
*/
public int[] getValues()
{
return values;
}

/**
* Returns the number of control values in this table.
*
* @return the entry count
*/
public int getValueCount()
{
return values != null ? values.length : 0;
}
}
Loading