| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- //
- // System.Drawing.Test.TextLineIterator.jvm.cs
- //
- // Author:
- // Konstantin Triger <[email protected]>
- //
- // Copyright (C) 2005 Mainsoft Corporation, (http://www.mainsoft.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Drawing.Drawing2D;
- using font = java.awt.font;
- using text = java.text;
- using awt = java.awt;
- using geom = java.awt.geom;
- namespace System.Drawing.Text {
- internal sealed class TextLineIterator {
- #region Fields
- readonly float _width;
- readonly float _height;
- readonly StringFormat _format;
- readonly font.FontRenderContext _frc;
- readonly string _s;
- readonly Font _font;
- readonly float _margin;
- static readonly string NewLine;
- static readonly geom.AffineTransform Rotate90Transform =
- geom.AffineTransform.getRotateInstance(Math.PI/2);
- font.TextMeasurer _measurer;
- int _charsConsumed = 0;
- int _currentPos = 0;
- int _currentRun = 0;
- float _accumulatedHeight = 0;
- #endregion
- #region ctors
- static TextLineIterator() {
- string newLine = Environment.NewLine;
- if (newLine == null || newLine.Length == 0 || newLine[newLine.Length - 1] == '\n')
- newLine = "\n";
- NewLine = newLine;
- }
- internal TextLineIterator(string s, Font font, font.FontRenderContext frc, StringFormat format, float width, float height) {
- _format = (format != null) ? format : new StringFormat();
- _font = font;
- _s = (s != null) ? s : String.Empty;
- _frc = frc;
- FontFamily ff = font.FontFamily;
- _margin = font.Size*ff.GetDrawMargin(font.Style)/ff.GetEmHeight(font.Style);
- _width = width;
- _height = height;
- }
- #endregion
- #region Properties
- float WrapWidth {
- get { return (_format.IsVertical ? Height : Width) - (Margin * 2); }
- }
- internal float WrapHeight {
- get { return (_format.IsVertical ? Width : Height); }
- }
- internal float Width {
- get { return _width; }
- }
- internal float Height {
- get { return _height; }
- }
- internal StringFormat Format {
- get { return _format; }
- }
- internal float Margin {
- get { return _margin; }
- }
- internal int CharsConsumed {
- get { return _charsConsumed; }
- }
- internal int CurrentRun {
- get { return _currentRun; }
- }
- internal int CurrentPosition {
- get { return _currentPos; }
- }
- internal float AccumulatedHeight {
- get { return _accumulatedHeight; }
- }
- internal float GetAdvanceBetween(int start, int limit) {
- return _measurer.getAdvanceBetween(start, limit);
- }
- internal geom.AffineTransform Transform {
- get { return Format.IsVertical ? Rotate90Transform : Matrix.IdentityTransform.NativeObject; }
- }
- #endregion
- #region Methods
- LineLayout NextTextLayoutFromMeasurer() {
- if (_accumulatedHeight >= WrapHeight) {
- _charsConsumed += _currentPos;
- return null;
- }
- int limit = _measurer.getLineBreakIndex(_currentPos, WrapWidth);
- int wordBreak = limit;
- if (wordBreak < _currentRun) {
- while (wordBreak >= _currentPos && char.IsLetterOrDigit(_s, _charsConsumed + wordBreak))
- wordBreak--;
- if (wordBreak > _currentPos)
- limit = wordBreak + 1;
- }
- font.TextLayout layout = _measurer.getLayout(_currentPos, limit);
-
- LineLayout lineLayout = new LineLayout(
- layout,
- this,
- _accumulatedHeight);
- float lineHeight = lineLayout.Ascent + lineLayout.Descent;
-
- if (Format.LineLimit && (_accumulatedHeight + lineHeight > WrapHeight)) {
- _charsConsumed += _currentPos;
- return null;
- }
- _accumulatedHeight += lineHeight + lineLayout.Leading;
- _currentPos = limit;
- while (_currentPos < _currentRun) {
- if (char.IsWhiteSpace(_s, _charsConsumed + _currentPos))
- _currentPos++;
- else
- break;
- }
- return lineLayout;
- }
- internal LineLayout NextLine() {
- if (_currentPos < _currentRun && !Format.NoWrap)
- return NextTextLayoutFromMeasurer();
- _charsConsumed += _currentRun;
- if (_charsConsumed >= _s.Length)
- return null;
- string s;
- int lineBreakIndex = _s.IndexOf(NewLine, _charsConsumed);
- if (lineBreakIndex >= 0) {
- s = _s.Substring(_charsConsumed, lineBreakIndex - _charsConsumed + NewLine.Length);
- }
- else
- s = _s.Substring(_charsConsumed);
- _currentRun = s.Length;
- _currentPos = 0;
- text.AttributedString aS = new text.AttributedString(s);
-
- // TODO: add more attribs according to StringFormat
- aS.addAttribute(font.TextAttribute.FONT, _font.NativeObject);
- if((_font.Style & FontStyle.Underline) != FontStyle.Regular)
- aS.addAttribute(font.TextAttribute.UNDERLINE, font.TextAttribute.UNDERLINE_ON);
- if((_font.Style & FontStyle.Strikeout) != FontStyle.Regular)
- aS.addAttribute(font.TextAttribute.STRIKETHROUGH, font.TextAttribute.STRIKETHROUGH_ON);
- text.AttributedCharacterIterator charIter = aS.getIterator();
- _measurer = new font.TextMeasurer(charIter, _frc);
- return NextTextLayoutFromMeasurer();
- }
- internal geom.AffineTransform CalcLineAlignmentTransform() {
- if (Format.LineAlignment == StringAlignment.Near)
- return null;
- float height = WrapHeight;
- if (float.IsPositiveInfinity(height))
- height = 0;
- float shift = height - AccumulatedHeight;
- if (height > 0 && shift <= 0)
- return null;
- if (Format.LineAlignment == StringAlignment.Center)
- shift /= 2;
- else
- if (Format.IsVertical && Format.IsRightToLeft)
- return null;
- return Format.IsVertical ?
- geom.AffineTransform.getTranslateInstance(shift, 0) :
- geom.AffineTransform.getTranslateInstance(0, shift);
- }
- #endregion
- }
- }
|