/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved.
*/
package org.pentaho.reporting.libraries.pixie.wmf.records;
import java.awt.Font;
import org.pentaho.reporting.libraries.pixie.wmf.MfLogFont;
import org.pentaho.reporting.libraries.pixie.wmf.MfRecord;
import org.pentaho.reporting.libraries.pixie.wmf.MfType;
import org.pentaho.reporting.libraries.pixie.wmf.WmfFile;
/**
* The CreateFontIndirect function creates a logical font that has the specified
* characteristics. The font can subsequently be selected as the current font for any
* device context.
* <p/>
* <code> typedef struct tagLOGFONT { LONG lfHeight; LONG lfWidth; LONG lfEscapement; LONG
* lfOrientation; LONG lfWeight; BYTE lfItalic; BYTE lfUnderline; BYTE lfStrikeOut; BYTE
* lfCharSet; BYTE lfOutPrecision; BYTE lfClipPrecision; BYTE lfQuality; BYTE
* lfPitchAndFamily; TCHAR lfFaceName[LF_FACESIZE]; } LOGFONT, *PLOGFONT; </code>
*/
public final class MfCmdCreateFont extends MfCmd
{
public static final int CHARSET_ANSI = 0;
public static final int CHARSET_DEFAULT = 1;
public static final int CHARSET_SYMBOL = 2;
public static final int CHARSET_SHIFTJIS = 128;
public static final int CHARSET_OEM = 255;
private static final int FONT_FACE_MAX = 31;
private static final int FIXED_RECORD_SIZE = 9;
private static final int POS_HEIGHT = 0;
private static final int POS_WIDTH = 1;
private static final int POS_ESCAPEMENT = 2;
private static final int POS_ORIENTATION = 3;
private static final int POS_WEIGHT = 4;
private static final int POS_FLAGS1 = 5;
private static final int POS_FLAGS2 = 6;
private static final int POS_PRECISION = 7;
private static final int POS_QUALITY = 8;
private static final int POS_FONTFACE = 9;
private int height;
private int width;
private int scaled_height;
private int scaled_width;
private int escapement;
private int orientation;
private int weight;
private boolean italic;
private boolean underline;
private boolean strikeout;
private int charset;
private int outprecision;
private int clipprecision;
private int quality;
private int pitchAndFamily;
private String facename;
public MfCmdCreateFont()
{
}
/**
* Replays the command on the given WmfFile.
*
* @param file the meta file.
*/
public void replay(final WmfFile file)
{
final MfLogFont lfont = new MfLogFont();
lfont.setFace(getFontFace());
lfont.setSize(getScaledHeight());
int style;
// should be bold ?
if (getWeight() > 650)
{
style = Font.BOLD;
}
else
{
style = Font.PLAIN;
}
if (isItalic())
{
style += Font.ITALIC;
}
lfont.setStyle(style);
lfont.setUnderline(isUnderline());
lfont.setStrikeOut(isStrikeout());
lfont.setRotation(getEscapement() / 10);
file.getCurrentState().setLogFont(lfont);
file.storeObject(lfont);
}
/**
* Creates a empty unintialized copy of this command implementation.
*
* @return a new instance of the command.
*/
public MfCmd getInstance()
{
return new MfCmdCreateFont();
}
/**
* Creates a new record based on the data stored in the MfCommand.
*
* @return the created record.
*/
public MfRecord getRecord()
{
String fontFace = getFontFace();
if (fontFace.length() > FONT_FACE_MAX)
{
fontFace = fontFace.substring(0, FONT_FACE_MAX);
}
final MfRecord record = new MfRecord(FIXED_RECORD_SIZE + fontFace.length());
record.setParam(POS_HEIGHT, getHeight());
record.setParam(POS_WIDTH, getWidth());
record.setParam(POS_ESCAPEMENT, getEscapement());
record.setParam(POS_ORIENTATION, getOrientation());
record.setParam(POS_WEIGHT, getWeight());
record.setParam(POS_FLAGS1, formFlags(isUnderline(), isItalic()));
record.setParam(POS_FLAGS2, formFlags(isStrikeout(), false) + getCharset());
record.setParam(POS_PRECISION, getOutputPrecision() << 8 + getClipPrecision());
record.setParam(POS_QUALITY, getQuality() << 8 + getPitchAndFamily());
record.setStringParam(POS_FONTFACE, fontFace);
return record;
}
public void setRecord(final MfRecord record)
{
int height = record.getParam(POS_HEIGHT);
if (height == 0)
{
// a default height is requested, we use a default height of 10
height = 10;
}
if (height < 0)
{
// windows specifiy font mapper matching, ignored.
height *= -1;
}
final int width = record.getParam(POS_WIDTH);
final int escape = record.getParam(POS_ESCAPEMENT);
final int orientation = record.getParam(POS_ORIENTATION);
final int weight = record.getParam(POS_WEIGHT);
final int italic = record.getParam(POS_FLAGS1) & 0x00FF;
final int underline = record.getParam(POS_FLAGS1) & 0xFF00;
final int strikeout = record.getParam(POS_FLAGS2) & 0x00FF;
final int charset = record.getParam(POS_FLAGS2) & 0xFF00;
final int outprec = record.getParam(POS_PRECISION) & 0x00FF;
final int clipprec = record.getParam(POS_PRECISION) & 0xFF00;
final int quality = record.getParam(POS_QUALITY) & 0x00FF;
final int pitch = record.getParam(POS_QUALITY) & 0xFF00;
// A fontname must not exceed the length of 32 including the null-terminator
final String facename = record.getStringParam(POS_FONTFACE, 32);
setCharset(charset);
setClipPrecision(clipprec);
setEscapement(escape);
setFontFace(facename);
setHeight(height);
setItalic(italic != 0);
setOrientation(orientation);
setOutputPrecision(outprec);
setPitchAndFamily(pitch);
setQuality(quality);
setStrikeout(strikeout != 0);
setUnderline(underline != 0);
setWeight(weight);
setWidth(width);
}
private int formFlags(final boolean f1, final boolean f2)
{
int retval = 0;
if (f1)
{
retval += 0x0100;
}
if (f2)
{
retval += 1;
}
return (retval);
}
/**
* Reads the function identifier. Every record type is identified by a function number
* corresponding to one of the Windows GDI functions used.
*
* @return the function identifier.
*/
public int getFunction()
{
return MfType.CREATE_FONT_INDIRECT;
}
public void setFontFace(final String facename)
{
this.facename = facename;
}
public String getFontFace()
{
return facename;
}
public void setPitchAndFamily(final int pitchAndFamily)
{
this.pitchAndFamily = pitchAndFamily;
}
public int getPitchAndFamily()
{
return pitchAndFamily;
}
public void setQuality(final int quality)
{
this.quality = quality;
}
public int getQuality()
{
return quality;
}
public void setClipPrecision(final int clipprecision)
{
this.clipprecision = clipprecision;
}
public int getClipPrecision()
{
return clipprecision;
}
public void setOutputPrecision(final int outprecision)
{
this.outprecision = outprecision;
}
public int getOutputPrecision()
{
return outprecision;
}
public void setCharset(final int charset)
{
this.charset = charset;
}
public int getCharset()
{
return charset;
}
public void setHeight(final int height)
{
this.height = height;
scaleYChanged();
}
public int getHeight()
{
return height;
}
public int getScaledHeight()
{
return scaled_height;
}
public void setWidth(final int width)
{
this.width = width;
scaleXChanged();
}
/**
* A callback function to inform the object, that the x scale has changed and the
* internal coordinate values have to be adjusted.
*/
protected void scaleXChanged()
{
scaled_width = getScaledX(width);
}
/**
* A callback function to inform the object, that the y scale has changed and the
* internal coordinate values have to be adjusted.
*/
protected void scaleYChanged()
{
scaled_height = getScaledY(height);
}
public int getWidth()
{
return width;
}
public int getScaledWidth()
{
return scaled_width;
}
// in 1/10 degrees
public void setEscapement(final int escapement)
{
this.escapement = escapement;
}
public int getEscapement()
{
return escapement;
}
// in 1/10 degrees
public void setOrientation(final int orientation)
{
this.orientation = orientation;
}
public int getOrientation()
{
return orientation;
}
// 200 = narrow
// 400 = normal
// 700 = bold
public void setWeight(final int weight)
{
this.weight = weight;
}
public int getWeight()
{
return weight;
}
public void setItalic(final boolean italic)
{
this.italic = italic;
}
public boolean isItalic()
{
return this.italic;
}
public void setUnderline(final boolean ul)
{
this.underline = ul;
}
public boolean isUnderline()
{
return this.underline;
}
public void setStrikeout(final boolean so)
{
this.strikeout = so;
}
public boolean isStrikeout()
{
return this.strikeout;
}
public String toString()
{
final StringBuffer b = new StringBuffer();
b.append("[CREATE_FONT] face=");
b.append(getFontFace());
b.append(" height=");
b.append(getHeight());
b.append(" width=");
b.append(getWidth());
b.append(" weight=");
b.append(getWeight());
b.append(" italic=");
b.append(isItalic());
b.append(" Strikeout=");
b.append(isStrikeout());
b.append(" Underline=");
b.append(isUnderline());
b.append(" outprecision=");
b.append(getOutputPrecision());
b.append(" escapement=");
b.append(getEscapement());
return b.toString();
}
}