| /* ==================================================================== |
| 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.poi.sl.draw; |
| |
| import java.awt.Color; |
| import java.awt.Graphics2D; |
| import java.awt.font.TextAttribute; |
| import java.awt.font.TextLayout; |
| import java.text.AttributedCharacterIterator; |
| import java.text.AttributedString; |
| import java.text.CharacterIterator; |
| |
| public class DrawTextFragment implements Drawable { |
| final TextLayout layout; |
| final AttributedString str; |
| double x, y; |
| |
| public DrawTextFragment(TextLayout layout, AttributedString str) { |
| this.layout = layout; |
| this.str = str; |
| } |
| |
| public void setPosition(double x, double y) { |
| // TODO: replace it, by applyTransform???? |
| this.x = x; |
| this.y = y; |
| } |
| |
| public void draw(Graphics2D graphics){ |
| if(str == null) { |
| return; |
| } |
| |
| double yBaseline = y + layout.getAscent(); |
| |
| Integer textMode = (Integer)graphics.getRenderingHint(Drawable.TEXT_RENDERING_MODE); |
| if(textMode != null && textMode == Drawable.TEXT_AS_SHAPES){ |
| layout.draw(graphics, (float)x, (float)yBaseline); |
| } else { |
| try { |
| graphics.drawString(str.getIterator(), (float) x, (float) yBaseline); |
| } catch (ClassCastException e) { |
| // workaround: batik issue, which expects only Color as forground color |
| replaceForgroundPaintWithBlack(str); |
| graphics.drawString(str.getIterator(), (float) x, (float) yBaseline); |
| } |
| } |
| } |
| |
| private void replaceForgroundPaintWithBlack(AttributedString as) { |
| AttributedCharacterIterator iter = as.getIterator(new TextAttribute[]{TextAttribute.FOREGROUND}); |
| for (char ch = iter.first(); |
| ch != CharacterIterator.DONE; |
| ch = iter.next()) { |
| as.addAttribute(TextAttribute.FOREGROUND, Color.BLACK, iter.getBeginIndex(), iter.getEndIndex()); |
| } |
| } |
| |
| public void applyTransform(Graphics2D graphics) { |
| } |
| |
| public void drawContent(Graphics2D graphics) { |
| } |
| |
| public TextLayout getLayout() { |
| return layout; |
| } |
| |
| public AttributedString getAttributedString() { |
| return str; |
| } |
| |
| /** |
| * @return full height of this text run which is sum of ascent, descent and leading |
| */ |
| public float getHeight(){ |
| double h = layout.getAscent() + layout.getDescent(); |
| return (float)h; |
| } |
| |
| /** |
| * @return the leading height before/after a text line |
| */ |
| public float getLeading() { |
| // fix invalid leadings (leading == 0) |
| double l = layout.getLeading(); |
| |
| if (l == 0) { |
| // see https://stackoverflow.com/questions/925147 |
| // we use a 115% value instead of the 120% proposed one, as this seems to be closer to LO/OO |
| l = (layout.getAscent()+layout.getDescent())*0.15; |
| } |
| return (float)l; |
| } |
| |
| /** |
| * |
| * @return width if this text run |
| */ |
| public float getWidth(){ |
| return layout.getAdvance(); |
| } |
| |
| /** |
| * |
| * @return the string to be painted |
| */ |
| public String getString(){ |
| if (str == null) return ""; |
| |
| AttributedCharacterIterator it = str.getIterator(); |
| StringBuilder buf = new StringBuilder(); |
| for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { |
| buf.append(c); |
| } |
| return buf.toString(); |
| } |
| |
| @Override |
| public String toString(){ |
| return "[" + getClass().getSimpleName() + "] " + getString(); |
| } |
| |
| } |