📄 interlinearizer.java
字号:
/* * File: Interlinearizer.java * Project: MPI Linguistic Application * Date: 02 May 2007 * * Copyright (C) 2001-2007 Max Planck Institute for Psycholinguistics * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * Created on Sep 24, 2004 */package mpi.eudico.server.corpora.clomimpl.shoebox.interlinear;import mpi.eudico.server.corpora.clom.Annotation;import mpi.eudico.server.corpora.clom.Tier;import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;import mpi.eudico.server.corpora.clomimpl.type.LinguisticType;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.util.Arrays;import java.util.Enumeration;import java.util.Hashtable;import java.util.Iterator;import java.util.List;import java.util.Vector;/** * Interlinearizer renders a range of different interlinear views. These views * differ with respect to their 'unit of alignment' and can be controlled by a * number of configuration settings. Possible 'units of alignment' are pixels * (drawing is on a BufferedImage that can be used for ELAN's interlinear * viewer, for printout or for a web application) and bytes (can be used for * Shoebox/Toolbox file output). The role of Interlinearizer is to store and * manage configuration parameters, and to control the rendering process by * delegating subtasks to the appropriate helper classes. Interlinearizer uses * a Metrics object to store and pass around size and position information. * * @author hennie */public class Interlinearizer { // constants // units for page width and height /** Holds value of property DOCUMENT ME! */ public static final int CM = 0; /** Holds value of property DOCUMENT ME! */ public static final int INCH = 1; /** Holds value of property DOCUMENT ME! */ public static final int PIXEL = 2; // wrap styles for blocks and lines /** Holds value of property DOCUMENT ME! */ public static final int EACH_BLOCK = 0; /** Holds value of property DOCUMENT ME! */ public static final int BLOCK_BOUNDARY = 1; /** Holds value of property DOCUMENT ME! */ public static final int WITHIN_BLOCKS = 2; /** Holds value of property DOCUMENT ME! */ public static final int NO_WRAP = 3; // time code types /** Holds value of property DOCUMENT ME! */ public static final int HHMMSSMS = 0; /** Holds value of property DOCUMENT ME! */ public static final int SSMS = 1; // strings for unaligned time codes /** Holds value of property DOCUMENT ME! */ public static final String UNALIGNED_HHMMSSMS = "??:??:??:???"; /** Holds value of property DOCUMENT ME! */ public static final String UNALIGNED_SSMS = "?.???"; // unit for text alignment /** Holds value of property DOCUMENT ME! */ public static final int PIXELS = 0; /** Holds value of property DOCUMENT ME! */ public static final int BYTES = 1; // font // public static Font DEFAULTFONT = new Font("SansSerif", Font.PLAIN, 12); /** Holds value of property DOCUMENT ME! */ public static Font DEFAULTFONT = new Font("MS Arial Unicode", Font.PLAIN, 12); /** Holds value of property DOCUMENT ME! */ public static final int DEFAULT_FONT_SIZE = 12; /** Holds value of property DOCUMENT ME! */ public static final int TIMECODE_FONT_SIZE = 10; // empty line style /** Holds value of property DOCUMENT ME! */ public static final int TEMPLATE = 0; /** Holds value of property DOCUMENT ME! */ public static final int HIDE_EMPTY_LINES = 1; // sorting style /** Holds value of property DOCUMENT ME! */ public static final int EXTERNALLY_SPECIFIED = 0; /** Holds value of property DOCUMENT ME! */ public static final int TIER_HIERARCHY = 1; /** Holds value of property DOCUMENT ME! */ public static final int BY_LINGUISTIC_TYPE = 2; /** Holds value of property DOCUMENT ME! */ public static final int BY_PARTICIPANT = 3; // character encoding /** Holds value of property DOCUMENT ME! */ public static final int UTF8 = 0; /** Holds value of property DOCUMENT ME! */ public static final int ISOLATIN = 1; /** Holds value of property DOCUMENT ME! */ public static final int SIL = 2; // other /** Holds value of property DOCUMENT ME! */ public static double SCALE = 300.0 / 72.0; // from 72 dpi to 300 dpi // members private TimeCodedTranscription transcription = null; private int width; private int height; private String[] visibleTiers; private boolean tierLabelsShown; private long[] visibleTimeInterval; private int blockWrapStyle; private int lineWrapStyle; private boolean timeCodeShown; private int timeCodeType; private Hashtable fonts; private Hashtable fontSizes; private boolean emptySlotsShown; private int lineSpacing; private int blockSpacing = -1; private Annotation activeAnnotation; private long[] selection; private long mediaTime; private int alignmentUnit; private int emptyLineStyle; // show full 'template' for block, or hide empty lines private int sortingStyle; private Hashtable charEncodings; private Metrics metrics; // private BufferedImage bi; private boolean forPrinting = false; private boolean renderingFirstPage = true; private int pageHeight = 0; private boolean sorted = false; private boolean correctAnnotationTimes = false; /** * Creates a new Interlinearizer instance * * @param tr DOCUMENT ME! */ public Interlinearizer(TimeCodedTranscription tr) { transcription = tr; metrics = new Metrics(tr, this); setDefaultValues(); } private void resetMetrics() { metrics.reset(); } private void setDefaultValues() { tierLabelsShown = true; blockWrapStyle = NO_WRAP; lineWrapStyle = NO_WRAP; timeCodeShown = false; timeCodeType = HHMMSSMS; emptySlotsShown = false; alignmentUnit = PIXELS; emptyLineStyle = HIDE_EMPTY_LINES; sortingStyle = EXTERNALLY_SPECIFIED; // set default visible tiers to all tier names if (transcription != null) { Vector tiers = transcription.getTiers(); visibleTiers = new String[tiers.size()]; for (int i = 0; i < tiers.size(); i++) { String tName = ((Tier) tiers.elementAt(i)).getName(); visibleTiers[i] = tName; } } // defaults for font and fontsizes fonts = new Hashtable(); fontSizes = new Hashtable(); charEncodings = new Hashtable(); } /** * DOCUMENT ME! * * @param bi DOCUMENT ME! */ public void renderView(BufferedImage bi) { if (this.isTimeCodeShown()) { transcription.prepareTimeCodeRendering(getTimeCodeType(), correctAnnotationTimes); addTimeCodeTiers(false); } calculateMetrics(bi.getGraphics()); } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String[] renderAsText() { if (this.isTimeCodeShown()) { transcription.prepareTimeCodeRendering(getTimeCodeType(), correctAnnotationTimes); addTimeCodeTiers(true); } calculateMetrics(); return ByteRenderer.render(metrics); } /** * DOCUMENT ME! * * @param g DOCUMENT ME! * @param pageWidth DOCUMENT ME! * @param pageHeight DOCUMENT ME! * @param pageIndex DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean renderPage(Graphics g, int pageWidth, int pageHeight, int pageIndex) { boolean pageExists = false; this.setWidth(pageWidth); this.setHeight(pageHeight); // first page if (renderingFirstPage) { if (this.isTimeCodeShown()) { transcription.prepareTimeCodeRendering(getTimeCodeType(), correctAnnotationTimes); addTimeCodeTiers(false); } calculateMetrics(g); renderingFirstPage = false; } // all pages pageExists = drawPage(g, pageIndex); // no more pages if (!pageExists) { if (isTimeCodeShown()) { transcription.cleanupTimeCodeTiers(); removeTimeCodeTiers(); } } return pageExists; } /** * Adjusts visibleTiers to show time code tiers for 'tier bundles' with one * or more visible tiers. The tc tiers are positioned right after the last * visible tier of their bundle. * * @param atTopOfBlock DOCUMENT ME! */ private void addTimeCodeTiers(boolean atTopOfBlock) { // clean up first removeTimeCodeTiers(); Vector tcTiers = transcription.getTimeCodeTiers(); Vector vTierVector = new Vector(Arrays.asList(visibleTiers)); // if tcTier has a root tier in common with a visible tier, then // it is visible. Add at proper position to vTierList. for (int j = 0; j < tcTiers.size(); j++) { Tier tcTier = (Tier) tcTiers.elementAt(j); // set font size for time code tiers // find minimum font size for visible tiers int minSize = TIMECODE_FONT_SIZE; for (int i = 0; i < vTierVector.size(); i++) { int sz = this.getFontSize((String) vTierVector.elementAt(i)); if (sz < minSize) { minSize = sz; } } setFontSize(tcTier.getName(), minSize); Tier rootTier = transcription.getRootTier(tcTier); // iterate over visibleTiers, remember position of last tier // that has same root tier as tcTier int lastIndex = -1; int firstIndex = -1; int index = 0; Iterator vTierIter = vTierVector.iterator(); while (vTierIter.hasNext()) { String visTierName = (String) vTierIter.next(); Tier visTier = transcription.getTranscription().getTierWithId(visTierName); TierImpl rootOfVisTier = transcription.getRootTier(visTier); if ((rootOfVisTier != null) && (rootTier == rootOfVisTier)) { lastIndex = index; if (firstIndex == -1) { // not yet set firstIndex = index; } } index++; } if (atTopOfBlock && (firstIndex >= 0)) { vTierVector.add(firstIndex + 1, tcTier.getName()); continue; } if (lastIndex >= 0) { vTierVector.add(lastIndex + 1, tcTier.getName()); } } int counter = 0; String[] newVisTiers = new String[vTierVector.size()]; Iterator vIter = vTierVector.iterator(); while (vIter.hasNext()) { String newTierName = newTierName = (String) vIter.next(); newVisTiers[counter] = newTierName; counter++; } setVisibleTiers(newVisTiers); } private void removeTimeCodeTiers() { Vector newVTierVector = new Vector(); for (int i = 0; i < visibleTiers.length; i++) { String vTierName = visibleTiers[i]; if (!vTierName.startsWith(TimeCodedTranscription.TC_TIER_PREFIX)) { newVTierVector.add(vTierName); } else if (fontSizes.contains(vTierName)) { fontSizes.remove(vTierName); } } String[] newVisTiers = new String[newVTierVector.size()]; for (int i = 0; i < newVTierVector.size(); i++) { newVisTiers[i] = (String) newVTierVector.elementAt(i); } setVisibleTiers(newVisTiers); } private void calculateMetrics(Graphics graphics) { resetMetrics(); SizeCalculator.calculateSizes(metrics, graphics); SizeCalculator.calculateUsedWidths(metrics); Positioner.calcHorizontalPositions(metrics); if ((lineWrapStyle != NO_WRAP) || (blockWrapStyle != NO_WRAP)) { Positioner.wrap(metrics); } if (emptyLineStyle == HIDE_EMPTY_LINES) { Positioner.hideEmptyLines(metrics); } } /** * Calculates metrics based on byte-wise alignment. */ private void calculateMetrics() { resetMetrics(); SizeCalculator.calculateSizes(metrics); SizeCalculator.calculateUsedWidths(metrics); Positioner.calcHorizontalPositions(metrics); if ((lineWrapStyle != NO_WRAP) || (blockWrapStyle != NO_WRAP)) { Positioner.wrap(metrics); } if (emptyLineStyle == HIDE_EMPTY_LINES) { Positioner.hideEmptyLines(metrics); } } /** * DOCUMENT ME! * * @param bi DOCUMENT ME! * @param offset DOCUMENT ME! */ public void drawViewOnImage(BufferedImage bi, int[] offset) { if (alignmentUnit == PIXELS) { // call to renderView should be consistent with params ImageRenderer.render(metrics, bi, offset); } } private boolean drawPage(Graphics g, int pageIndex) { boolean pageExists = true; if (alignmentUnit == PIXELS) { // call to renderView should be consistent with params pageExists = ImageRenderer.render(metrics, g, pageIndex); } return pageExists; } // getters and setters /** * DOCUMENT ME! * * @return */ public Annotation getActiveAnnotation() { return activeAnnotation; } /** * DOCUMENT ME! * * @return */ public int getAlignmentUnit() { return alignmentUnit; } /** * DOCUMENT ME! * * @return */ public int getBlockWrapStyle() { return blockWrapStyle; } /** * DOCUMENT ME! * * @return */ public boolean isEmptySlotsShown() { return emptySlotsShown; } /** * DOCUMENT ME! * * @param tierName DOCUMENT ME! * * @return */ public Font getFont(String tierName) { Font f = (Font) fonts.get(tierName); if (f == null) { // use default font f = DEFAULTFONT; } return f; } /** * DOCUMENT ME! * * @param tierName DOCUMENT ME! * * @return */ public int getFontSize(String tierName) { int size = 0; Integer sizeInt = (Integer) fontSizes.get(tierName); if (sizeInt != null) { size = sizeInt.intValue(); } else { size = DEFAULT_FONT_SIZE; } return size; } /** * DOCUMENT ME! * * @return */ public int getHeight() { if (height > 0) { return height; } else { // find width from max horizontally used space return metrics.getMaxVerticalPosition(); } } /** * DOCUMENT ME! * * @return */ public int getLineSpacing() { return lineSpacing; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -