annotate font/font_layout.cc @ 66:d112357a0ec1

Fix a bug with savegames introduced with changeset c7bcc0ec2267. Warning: savegames created since c7bcc0ec2267 are probably corrupted, you may have to start the game over. If you chose not to do so, you should replace all occurrences of 'TextWindow' by 'TextImplWindow', and 'Text Window' by 'TextImpl Window' in your save files.
author Thibaut Girka <thib@sitedethib.com>
date Sat, 11 Dec 2010 18:36:20 +0100
parents 4416cfac86ae
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
223b71206888 Initial import
thib
parents:
diff changeset
1 /* layout2.cc
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
2 * テキストの禁則処理、レイアウトなどを行う
0
223b71206888 Initial import
thib
parents:
diff changeset
3 */
223b71206888 Initial import
thib
parents:
diff changeset
4 /*
223b71206888 Initial import
thib
parents:
diff changeset
5 * Copyright (c) 2004-2006 Kazunori "jagarl" Ueno
223b71206888 Initial import
thib
parents:
diff changeset
6 * All rights reserved.
223b71206888 Initial import
thib
parents:
diff changeset
7 *
223b71206888 Initial import
thib
parents:
diff changeset
8 * Redistribution and use in source and binary forms, with or without
223b71206888 Initial import
thib
parents:
diff changeset
9 * modification, are permitted provided that the following conditions
223b71206888 Initial import
thib
parents:
diff changeset
10 * are met:
223b71206888 Initial import
thib
parents:
diff changeset
11 * 1. Redistributions of source code must retain the above copyright
223b71206888 Initial import
thib
parents:
diff changeset
12 * notice, this list of conditions and the following disclaimer.
223b71206888 Initial import
thib
parents:
diff changeset
13 * 2. Redistributions in binary form must reproduce the above copyright
223b71206888 Initial import
thib
parents:
diff changeset
14 * notice, this list of conditions and the following disclaimer in the
223b71206888 Initial import
thib
parents:
diff changeset
15 * documentation and/or other materials provided with the distribution.
223b71206888 Initial import
thib
parents:
diff changeset
16 * 3. The name of the author may not be used to endorse or promote products
223b71206888 Initial import
thib
parents:
diff changeset
17 * derived from this software without specific prior written permission.
223b71206888 Initial import
thib
parents:
diff changeset
18 *
223b71206888 Initial import
thib
parents:
diff changeset
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
223b71206888 Initial import
thib
parents:
diff changeset
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
223b71206888 Initial import
thib
parents:
diff changeset
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
223b71206888 Initial import
thib
parents:
diff changeset
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
223b71206888 Initial import
thib
parents:
diff changeset
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
223b71206888 Initial import
thib
parents:
diff changeset
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
223b71206888 Initial import
thib
parents:
diff changeset
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
223b71206888 Initial import
thib
parents:
diff changeset
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
223b71206888 Initial import
thib
parents:
diff changeset
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
223b71206888 Initial import
thib
parents:
diff changeset
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
223b71206888 Initial import
thib
parents:
diff changeset
29 */
223b71206888 Initial import
thib
parents:
diff changeset
30
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
31 #include <vector>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
32 #include <map>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
33 #include <iostream>
0
223b71206888 Initial import
thib
parents:
diff changeset
34
223b71206888 Initial import
thib
parents:
diff changeset
35 using namespace std;
223b71206888 Initial import
thib
parents:
diff changeset
36
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
37 #include "font.h"
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
38 #include "text.h"
0
223b71206888 Initial import
thib
parents:
diff changeset
39
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
40 const int line_skip = 1; // 行と行の間の間隔
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
41 const int ruby_textskip = 0; // 文字とルビの間の間隔
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
42 const int ruby_lineskip = 1; // ルビがあるときに行間に加える値
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
43 const double ruby_scale = 0.4; // ルビのスケール
0
223b71206888 Initial import
thib
parents:
diff changeset
44
223b71206888 Initial import
thib
parents:
diff changeset
45 class TextGlyphStreamHelper;
223b71206888 Initial import
thib
parents:
diff changeset
46
223b71206888 Initial import
thib
parents:
diff changeset
47 enum KinsokuType { KinsokuHead = 1, KinsokuTail = 2};
223b71206888 Initial import
thib
parents:
diff changeset
48 static int kinsoku_table1[] = {
223b71206888 Initial import
thib
parents:
diff changeset
49 /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 */
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
50 0,0,2,2,2,2,0,0, /* X 、。,.・: */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
51 0,2,2,0,0,0,0,0, /* ;?!゛゜´`¨ */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
52 0,0,0,0,0,0,0,0, /* ^ ̄_ヽヾゝゞ〃 */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
53 0,0,0,0,2,0,0,0, /* 仝々〆〇ー―‐/ */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
54 0,2,0,0,2,2,1,2, /* \〜‖|…‥‘’ */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
55 1,2,1,2,1,2,1,2, /* “”()〔〕[] */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
56 1,2,1,2,1,2,1,2, /* {}〈〉《》「」 */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
57 1,2,1,2,0,0,0,0, /* 『』【】+−±× */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
58 0,0,0,0,0,0,0,0, /* ÷=≠<>≦≧∞ */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
59 0,0,0,0,0,0,0,0, /* ∴♂♀°′″℃¥ */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
60 0,0,0,0,0,0,0,0, /* $¢£%#&*@ */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
61 0,0,0,0,0,0,0,0, /* §☆★○●◎◇X */
0
223b71206888 Initial import
thib
parents:
diff changeset
62 0
223b71206888 Initial import
thib
parents:
diff changeset
63 };
223b71206888 Initial import
thib
parents:
diff changeset
64 static int kinsoku_table2[] = {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
65 0,2,0,2,0,2,0,2,0,2,0,0,0,0,0,0, /*  ぁあぃいぅうぇえぉおかがきぎく */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
66 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ぐけげこごさざしじすずせぜそぞた */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
67 0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, /* だちぢっつづてでとどなにぬねのは */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
68 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ばぱひびぴふぶぷへべぺほぼぽまみ */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
69 0,0,0,2,0,2,0,2,0,0,0,0,0,0,2,0, /* むめもゃやゅゆょよらりるれろゎわ */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
70 0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0, /* ゐゑをんヴヵヶ */
0
223b71206888 Initial import
thib
parents:
diff changeset
71 0
223b71206888 Initial import
thib
parents:
diff changeset
72 };
223b71206888 Initial import
thib
parents:
diff changeset
73
223b71206888 Initial import
thib
parents:
diff changeset
74 inline int Kinsoku(int code) {
223b71206888 Initial import
thib
parents:
diff changeset
75 if ( (code&0xff80) == 0xa180) return kinsoku_table1[ (code&0xff) - 0xa0];
223b71206888 Initial import
thib
parents:
diff changeset
76 if ( (code&0xfe80) == 0xa480) return kinsoku_table2[ (code&0xff) - 0xa0]; /* code = 0xa400 / 0xa500 */
223b71206888 Initial import
thib
parents:
diff changeset
77 return 0;
223b71206888 Initial import
thib
parents:
diff changeset
78 }
223b71206888 Initial import
thib
parents:
diff changeset
79
223b71206888 Initial import
thib
parents:
diff changeset
80 class TextGlyphStreamHelper {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
81 private:
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
82 typedef TextStream::Iterator Iterator;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
83 typedef TextGlyphStream::iterator iterator;
0
223b71206888 Initial import
thib
parents:
diff changeset
84
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
85 TextGlyphStream* data;
0
223b71206888 Initial import
thib
parents:
diff changeset
86
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
87 // information for rendering
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
88 unsigned char r, g, b;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
89 XKFont::Face* face;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
90 XKFont::Face* ruby_face;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
91 XKFont::Font* font;
0
223b71206888 Initial import
thib
parents:
diff changeset
92
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
93 public:
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
94 int min_lineheight;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
95 TextGlyphStreamHelper(XKFont::Font* font);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
96 // helper functions
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
97 void Init(TextGlyphStream* data);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
98 Iterator Add(int& x, Iterator begin, Iterator end, int max_x = 0);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
99 Iterator AddRuby(int& x, Iterator begin, Iterator end);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
100 int CharWidth(int code);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
101 void SetGroup(iterator begin, iterator end);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
102 void CalcHeight(int& ascent, int& descent, iterator begin, iterator end);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
103 void AdjustPosition(int xstart_add, int xend_add, int y_add, iterator begin, iterator end);
0
223b71206888 Initial import
thib
parents:
diff changeset
104 };
223b71206888 Initial import
thib
parents:
diff changeset
105
223b71206888 Initial import
thib
parents:
diff changeset
106 TextGlyphStreamHelper::TextGlyphStreamHelper(XKFont::Font* __font) {
223b71206888 Initial import
thib
parents:
diff changeset
107 font = __font;
223b71206888 Initial import
thib
parents:
diff changeset
108 face = font->FaceLoad(1.0);
223b71206888 Initial import
thib
parents:
diff changeset
109 ruby_face = 0;
223b71206888 Initial import
thib
parents:
diff changeset
110 r = 255; g = 255; b = 255;
223b71206888 Initial import
thib
parents:
diff changeset
111 min_lineheight = font->vsize;
223b71206888 Initial import
thib
parents:
diff changeset
112 }
223b71206888 Initial import
thib
parents:
diff changeset
113
223b71206888 Initial import
thib
parents:
diff changeset
114 void TextGlyphStreamHelper::Init(TextGlyphStream* __data) {
223b71206888 Initial import
thib
parents:
diff changeset
115 r = 255; g = 255; b = 255;
223b71206888 Initial import
thib
parents:
diff changeset
116 face = font->FaceLoad(1.0);
223b71206888 Initial import
thib
parents:
diff changeset
117 data = __data;
223b71206888 Initial import
thib
parents:
diff changeset
118 data->clear();
223b71206888 Initial import
thib
parents:
diff changeset
119 data->font = font;
223b71206888 Initial import
thib
parents:
diff changeset
120 }
223b71206888 Initial import
thib
parents:
diff changeset
121
223b71206888 Initial import
thib
parents:
diff changeset
122 TextGlyphStreamHelper::Iterator
223b71206888 Initial import
thib
parents:
diff changeset
123 TextGlyphStreamHelper::Add(int& x, TextGlyphStreamHelper::Iterator begin, TextGlyphStreamHelper::Iterator end, int max_x) {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
124 /* text を glyph に変換する */
0
223b71206888 Initial import
thib
parents:
diff changeset
125 TextGlyph gl;
223b71206888 Initial import
thib
parents:
diff changeset
126 Iterator it;
223b71206888 Initial import
thib
parents:
diff changeset
127 gl.x = x; gl.y = 0; gl.r = r; gl.g = g; gl.b = b; gl.flag = TextGlyph::Flag(0); gl.is_rev = false;
223b71206888 Initial import
thib
parents:
diff changeset
128 for (it = begin; it != end; it++) {
223b71206888 Initial import
thib
parents:
diff changeset
129 if (it->type != TextElem::glyph) {
223b71206888 Initial import
thib
parents:
diff changeset
130 if (it->type == TextElem::color) {
223b71206888 Initial import
thib
parents:
diff changeset
131 gl.r = r = it->impl.Color.r;
223b71206888 Initial import
thib
parents:
diff changeset
132 gl.g = g = it->impl.Color.g;
223b71206888 Initial import
thib
parents:
diff changeset
133 gl.b = b = it->impl.Color.b;
223b71206888 Initial import
thib
parents:
diff changeset
134 } else if (it->type == TextElem::size) {
50
35ce1a30f3f9 * Added va_end where there is a va_start
thib
parents: 0
diff changeset
135 delete face;
0
223b71206888 Initial import
thib
parents:
diff changeset
136 face = font->FaceLoad(it->impl.Size.scale);
223b71206888 Initial import
thib
parents:
diff changeset
137 } else if (it->type == TextElem::escape) {
223b71206888 Initial import
thib
parents:
diff changeset
138 x = gl.x;
223b71206888 Initial import
thib
parents:
diff changeset
139 return it;
223b71206888 Initial import
thib
parents:
diff changeset
140 }
223b71206888 Initial import
thib
parents:
diff changeset
141 continue;
223b71206888 Initial import
thib
parents:
diff changeset
142 }
223b71206888 Initial import
thib
parents:
diff changeset
143 try {
223b71206888 Initial import
thib
parents:
diff changeset
144 gl.glyph = face->GlyphLoad(it->impl.Glyph.code);
223b71206888 Initial import
thib
parents:
diff changeset
145 if (max_x > 0 && gl.x + gl.glyph->advance.x > max_x) {
223b71206888 Initial import
thib
parents:
diff changeset
146 x = gl.x;
223b71206888 Initial import
thib
parents:
diff changeset
147 return it;
223b71206888 Initial import
thib
parents:
diff changeset
148 }
223b71206888 Initial import
thib
parents:
diff changeset
149 if ( Kinsoku(it->impl.Glyph.code) == KinsokuTail)
223b71206888 Initial import
thib
parents:
diff changeset
150 gl.flag = TextGlyph::Flag(gl.flag | TextGlyph::Kinsoku);
223b71206888 Initial import
thib
parents:
diff changeset
151 else
223b71206888 Initial import
thib
parents:
diff changeset
152 gl.flag = TextGlyph::Flag(0);
223b71206888 Initial import
thib
parents:
diff changeset
153 data->push_back(gl);
223b71206888 Initial import
thib
parents:
diff changeset
154 gl.x += gl.glyph->advance.x;
223b71206888 Initial import
thib
parents:
diff changeset
155 } catch(...) {}
223b71206888 Initial import
thib
parents:
diff changeset
156 }
223b71206888 Initial import
thib
parents:
diff changeset
157 x = gl.x;
223b71206888 Initial import
thib
parents:
diff changeset
158 return it;
223b71206888 Initial import
thib
parents:
diff changeset
159 }
223b71206888 Initial import
thib
parents:
diff changeset
160
223b71206888 Initial import
thib
parents:
diff changeset
161 TextGlyphStreamHelper::Iterator TextGlyphStreamHelper::AddRuby(int& x, TextGlyphStreamHelper::Iterator sbegin, TextGlyphStreamHelper::Iterator send) {
223b71206888 Initial import
thib
parents:
diff changeset
162 Iterator it;
223b71206888 Initial import
thib
parents:
diff changeset
163 it = sbegin;
223b71206888 Initial import
thib
parents:
diff changeset
164 if (it == send) return it;
223b71206888 Initial import
thib
parents:
diff changeset
165 if (it->type != TextElem::escape || it->impl.Escape.type != TextElem::ruby_start) return sbegin;
223b71206888 Initial import
thib
parents:
diff changeset
166 it++;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
167 /* まず、本文描画 */
0
223b71206888 Initial import
thib
parents:
diff changeset
168 int str_firstpos = data->size();
223b71206888 Initial import
thib
parents:
diff changeset
169 int str_width = 0;
223b71206888 Initial import
thib
parents:
diff changeset
170 it = Add(str_width, it, send);
223b71206888 Initial import
thib
parents:
diff changeset
171 if (it == send || it->type != TextElem::escape || it->impl.Escape.type != TextElem::ruby_startruby) {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
172 // ありえないはずだが、取り合えずなにもしないで終了
0
223b71206888 Initial import
thib
parents:
diff changeset
173 cerr << "TextGlyphStream::AddRuby : invalid operation; fallback to the upeer level"<<endl;
223b71206888 Initial import
thib
parents:
diff changeset
174 data->erase(data->begin()+str_firstpos, data->end());
223b71206888 Initial import
thib
parents:
diff changeset
175 return sbegin+1;
223b71206888 Initial import
thib
parents:
diff changeset
176 }
223b71206888 Initial import
thib
parents:
diff changeset
177 it++;
223b71206888 Initial import
thib
parents:
diff changeset
178 int str_lastpos = data->size()-1;
223b71206888 Initial import
thib
parents:
diff changeset
179 TextGlyph& str_first = data->begin()[str_firstpos];
223b71206888 Initial import
thib
parents:
diff changeset
180 TextGlyph& str_last = data->back();
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
181 // 次に、フォントを取りかえてルビ描画
0
223b71206888 Initial import
thib
parents:
diff changeset
182 int ruby_firstpos = data->size();
223b71206888 Initial import
thib
parents:
diff changeset
183 XKFont::Face* save_font = face;
223b71206888 Initial import
thib
parents:
diff changeset
184 if (ruby_face == 0) ruby_face = font->FaceLoad(ruby_scale);
223b71206888 Initial import
thib
parents:
diff changeset
185 face = ruby_face;
223b71206888 Initial import
thib
parents:
diff changeset
186 int ruby_width = 0;
223b71206888 Initial import
thib
parents:
diff changeset
187 it = Add(ruby_width, it, send);
223b71206888 Initial import
thib
parents:
diff changeset
188 if (it->type != TextElem::escape || it->impl.Escape.type != TextElem::ruby_end) {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
189 /* ありえないはずだが、取り合えずなにもしないで終了 */
0
223b71206888 Initial import
thib
parents:
diff changeset
190 cerr << "TextGlyphStream::AddRuby : invalid operation; fallback to the upeer level"<<endl;
223b71206888 Initial import
thib
parents:
diff changeset
191 data->erase(data->begin()+str_firstpos, data->end());
223b71206888 Initial import
thib
parents:
diff changeset
192 return sbegin+1;
223b71206888 Initial import
thib
parents:
diff changeset
193 }
223b71206888 Initial import
thib
parents:
diff changeset
194 it++;
223b71206888 Initial import
thib
parents:
diff changeset
195 face = save_font;
223b71206888 Initial import
thib
parents:
diff changeset
196 TextGlyph& ruby_first = (*data)[ruby_firstpos];
223b71206888 Initial import
thib
parents:
diff changeset
197 TextGlyph& ruby_last = data->back();
223b71206888 Initial import
thib
parents:
diff changeset
198
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
199 /* ルビを移動すべき高さを求める */
0
223b71206888 Initial import
thib
parents:
diff changeset
200 int dummy, str_ascent, ruby_descent;
223b71206888 Initial import
thib
parents:
diff changeset
201 CalcHeight(str_ascent, dummy, data->begin()+str_firstpos, data->begin()+ruby_firstpos);
223b71206888 Initial import
thib
parents:
diff changeset
202 CalcHeight(dummy, ruby_descent, data->begin()+ruby_firstpos, data->end());
223b71206888 Initial import
thib
parents:
diff changeset
203 int ruby_height = str_ascent + ruby_descent + ruby_textskip;
223b71206888 Initial import
thib
parents:
diff changeset
204
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
205 /* センタリングした場合の、ルビの左側、右側のマージン */
0
223b71206888 Initial import
thib
parents:
diff changeset
206 int leftmergin, rightmergin;
223b71206888 Initial import
thib
parents:
diff changeset
207 leftmergin = str_first.glyph->advance.x/2 - (ruby_first.glyph->advance.x+1)/2;
223b71206888 Initial import
thib
parents:
diff changeset
208 rightmergin = str_last.glyph->advance.x/2 - (ruby_last.glyph->advance.x+1)/2;
223b71206888 Initial import
thib
parents:
diff changeset
209
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
210 /* ルビ、本文の横方向の移動 */
0
223b71206888 Initial import
thib
parents:
diff changeset
211 int ruby_xstart_add = 0, ruby_xend_add = 0, str_xstart_add=0, str_xend_add = 0;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
212 if (ruby_width+leftmergin+rightmergin <= str_width) { // ルビの方が小さい
0
223b71206888 Initial import
thib
parents:
diff changeset
213 ruby_xstart_add = leftmergin;
223b71206888 Initial import
thib
parents:
diff changeset
214 ruby_xend_add = str_width-rightmergin-ruby_width;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
215 } else if (ruby_width <= str_width) { // マージンを減らす必要あり
0
223b71206888 Initial import
thib
parents:
diff changeset
216 leftmergin = (str_width-ruby_width)/2;
223b71206888 Initial import
thib
parents:
diff changeset
217 ruby_xstart_add = leftmergin;
223b71206888 Initial import
thib
parents:
diff changeset
218 ruby_xend_add = str_width-leftmergin-ruby_width;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
219 } else { // ルビの方が大きい
0
223b71206888 Initial import
thib
parents:
diff changeset
220 int str_count = ruby_firstpos - str_firstpos;
223b71206888 Initial import
thib
parents:
diff changeset
221 str_xstart_add = ruby_width/str_count/2 - str_first.glyph->advance.x/2;
223b71206888 Initial import
thib
parents:
diff changeset
222 str_xend_add = (ruby_width-str_width) - (ruby_width/str_count/2-str_last.glyph->advance.x/2);
223b71206888 Initial import
thib
parents:
diff changeset
223 str_width = ruby_width;
223b71206888 Initial import
thib
parents:
diff changeset
224 }
223b71206888 Initial import
thib
parents:
diff changeset
225 AdjustPosition(str_xstart_add+x, str_xend_add+x, 0, data->begin()+str_firstpos, data->begin()+ruby_firstpos);
223b71206888 Initial import
thib
parents:
diff changeset
226 AdjustPosition(ruby_xstart_add+x, ruby_xend_add+x, -ruby_height, data->begin()+ruby_firstpos, data->end());
223b71206888 Initial import
thib
parents:
diff changeset
227
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
228 /* 本文が一文字ずつ表示されるように glyph の順番を入れかえ、グループ化 */
0
223b71206888 Initial import
thib
parents:
diff changeset
229 vector<TextGlyph> save;
223b71206888 Initial import
thib
parents:
diff changeset
230 save.assign(data->begin()+str_firstpos, data->end());
223b71206888 Initial import
thib
parents:
diff changeset
231 iterator it_str = save.begin();
223b71206888 Initial import
thib
parents:
diff changeset
232 iterator it_ruby = save.begin()+(ruby_firstpos-str_firstpos);
223b71206888 Initial import
thib
parents:
diff changeset
233 iterator dit = data->begin()+str_firstpos;
223b71206888 Initial import
thib
parents:
diff changeset
234 int str_count = it_ruby-it_str;
223b71206888 Initial import
thib
parents:
diff changeset
235 int ruby_count = save.end()-it_ruby;
223b71206888 Initial import
thib
parents:
diff changeset
236 int i,j = 0;
223b71206888 Initial import
thib
parents:
diff changeset
237 for (i=0; i<str_count; i++) {
223b71206888 Initial import
thib
parents:
diff changeset
238 iterator charstart = dit;
223b71206888 Initial import
thib
parents:
diff changeset
239 int jend = (i+1)*ruby_count/str_count;
223b71206888 Initial import
thib
parents:
diff changeset
240 for (; j<jend; j++) {
223b71206888 Initial import
thib
parents:
diff changeset
241 *dit++ = *it_ruby++;
223b71206888 Initial import
thib
parents:
diff changeset
242 }
223b71206888 Initial import
thib
parents:
diff changeset
243 *dit++ = *it_str++;
223b71206888 Initial import
thib
parents:
diff changeset
244 SetGroup(charstart, dit);
223b71206888 Initial import
thib
parents:
diff changeset
245 }
223b71206888 Initial import
thib
parents:
diff changeset
246 x += str_width;
223b71206888 Initial import
thib
parents:
diff changeset
247 return it;
223b71206888 Initial import
thib
parents:
diff changeset
248 }
223b71206888 Initial import
thib
parents:
diff changeset
249
223b71206888 Initial import
thib
parents:
diff changeset
250
223b71206888 Initial import
thib
parents:
diff changeset
251 void TextGlyphStreamHelper::SetGroup(TextGlyphStreamHelper::iterator begin, TextGlyphStreamHelper::iterator end) {
223b71206888 Initial import
thib
parents:
diff changeset
252 iterator it;
223b71206888 Initial import
thib
parents:
diff changeset
253 for (it = begin; it+1 != end; it++)
223b71206888 Initial import
thib
parents:
diff changeset
254 it->flag = TextGlyph::Flag(it->flag |TextGlyph::Group);
223b71206888 Initial import
thib
parents:
diff changeset
255 it->flag = TextGlyph::Flag(it->flag & ~TextGlyph::Group);
223b71206888 Initial import
thib
parents:
diff changeset
256 return;
223b71206888 Initial import
thib
parents:
diff changeset
257 }
223b71206888 Initial import
thib
parents:
diff changeset
258
223b71206888 Initial import
thib
parents:
diff changeset
259 void TextGlyphStreamHelper::AdjustPosition(int xstart_add, int xend_add, int y_add, TextGlyphStreamHelper::iterator begin, TextGlyphStreamHelper::iterator end) {
223b71206888 Initial import
thib
parents:
diff changeset
260 iterator it;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
261 /* 文字数を数える */
0
223b71206888 Initial import
thib
parents:
diff changeset
262 int total_count = 0;
223b71206888 Initial import
thib
parents:
diff changeset
263 for (it = begin; it != end; it++) {
223b71206888 Initial import
thib
parents:
diff changeset
264 if (it->flag & TextGlyph::Group) continue;
223b71206888 Initial import
thib
parents:
diff changeset
265 total_count++;
223b71206888 Initial import
thib
parents:
diff changeset
266 }
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
267 /* 文字間のギャップを変更 */
0
223b71206888 Initial import
thib
parents:
diff changeset
268 int incr = 0;
223b71206888 Initial import
thib
parents:
diff changeset
269 if (total_count != 1) incr = (xend_add - xstart_add) * 256 / (total_count-1);
223b71206888 Initial import
thib
parents:
diff changeset
270 int cur = xstart_add * 256;
223b71206888 Initial import
thib
parents:
diff changeset
271 for (it = begin; it != end; it++) {
223b71206888 Initial import
thib
parents:
diff changeset
272 it->x += cur / 256;
223b71206888 Initial import
thib
parents:
diff changeset
273 it->y += y_add;
223b71206888 Initial import
thib
parents:
diff changeset
274 if (it->flag & TextGlyph::Group) continue;
223b71206888 Initial import
thib
parents:
diff changeset
275 cur += incr;
223b71206888 Initial import
thib
parents:
diff changeset
276 }
223b71206888 Initial import
thib
parents:
diff changeset
277 return;
223b71206888 Initial import
thib
parents:
diff changeset
278 }
223b71206888 Initial import
thib
parents:
diff changeset
279 void TextGlyphStreamHelper::CalcHeight(int& ascent_r, int& descent_r, TextGlyphStreamHelper::iterator begin, TextGlyphStreamHelper::iterator end) {
223b71206888 Initial import
thib
parents:
diff changeset
280 iterator it;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
281 /* 最大の descent, ascent を計算 */
0
223b71206888 Initial import
thib
parents:
diff changeset
282 int ascent = 0;
223b71206888 Initial import
thib
parents:
diff changeset
283 int descent = 0;
223b71206888 Initial import
thib
parents:
diff changeset
284 for (it = begin; it != end; it++) {
223b71206888 Initial import
thib
parents:
diff changeset
285
223b71206888 Initial import
thib
parents:
diff changeset
286 int y_top = it->y - it->glyph->bitmap_top;
223b71206888 Initial import
thib
parents:
diff changeset
287 int y_bottom = it->y + it->glyph->bitmap.rows - it->glyph->bitmap_top;
223b71206888 Initial import
thib
parents:
diff changeset
288
223b71206888 Initial import
thib
parents:
diff changeset
289 if (descent < y_bottom) descent = y_bottom;
223b71206888 Initial import
thib
parents:
diff changeset
290 if (ascent < -y_top) ascent = -y_top;
223b71206888 Initial import
thib
parents:
diff changeset
291 }
223b71206888 Initial import
thib
parents:
diff changeset
292 ascent_r = ascent;
223b71206888 Initial import
thib
parents:
diff changeset
293 descent_r = descent;
223b71206888 Initial import
thib
parents:
diff changeset
294 return;
223b71206888 Initial import
thib
parents:
diff changeset
295 }
223b71206888 Initial import
thib
parents:
diff changeset
296
223b71206888 Initial import
thib
parents:
diff changeset
297 int TextGlyphStreamHelper::CharWidth(int code) {
223b71206888 Initial import
thib
parents:
diff changeset
298 try {
223b71206888 Initial import
thib
parents:
diff changeset
299 XKFont::Glyph* g = face->GlyphLoad(code);
223b71206888 Initial import
thib
parents:
diff changeset
300 return g->advance.x;
223b71206888 Initial import
thib
parents:
diff changeset
301 } catch(...) {
223b71206888 Initial import
thib
parents:
diff changeset
302 return 0;
223b71206888 Initial import
thib
parents:
diff changeset
303 }
223b71206888 Initial import
thib
parents:
diff changeset
304 }
223b71206888 Initial import
thib
parents:
diff changeset
305
223b71206888 Initial import
thib
parents:
diff changeset
306 class TextHorizLayout {
223b71206888 Initial import
thib
parents:
diff changeset
307 typedef TextStream::Iterator Iterator;
223b71206888 Initial import
thib
parents:
diff changeset
308
223b71206888 Initial import
thib
parents:
diff changeset
309 Iterator pos;
223b71206888 Initial import
thib
parents:
diff changeset
310 Iterator end;
223b71206888 Initial import
thib
parents:
diff changeset
311 TextGlyphStream* data;
223b71206888 Initial import
thib
parents:
diff changeset
312 TextGlyphStreamHelper helper;
223b71206888 Initial import
thib
parents:
diff changeset
313 int tab_width;
223b71206888 Initial import
thib
parents:
diff changeset
314 int cur_y;
223b71206888 Initial import
thib
parents:
diff changeset
315
223b71206888 Initial import
thib
parents:
diff changeset
316 void SetName(void);
223b71206888 Initial import
thib
parents:
diff changeset
317 void SetLineHead(void);
223b71206888 Initial import
thib
parents:
diff changeset
318 void MakeLine(int line_first, int width, vector<int>& lineheights);
223b71206888 Initial import
thib
parents:
diff changeset
319 public:
223b71206888 Initial import
thib
parents:
diff changeset
320 TextHorizLayout(XKFont::Font* font);
223b71206888 Initial import
thib
parents:
diff changeset
321 void Layout(TextStream& stream, TextGlyphStream& glyph, vector<int>& lineheights, int width);
223b71206888 Initial import
thib
parents:
diff changeset
322 };
223b71206888 Initial import
thib
parents:
diff changeset
323
223b71206888 Initial import
thib
parents:
diff changeset
324 TextHorizLayout::TextHorizLayout(XKFont::Font* font) :
223b71206888 Initial import
thib
parents:
diff changeset
325 helper(font), tab_width(0), cur_y(0) {
223b71206888 Initial import
thib
parents:
diff changeset
326 }
223b71206888 Initial import
thib
parents:
diff changeset
327
223b71206888 Initial import
thib
parents:
diff changeset
328 void TextHorizLayout::Layout(TextStream& stream, TextGlyphStream& glyph, vector<int>& lineheights, int width) {
223b71206888 Initial import
thib
parents:
diff changeset
329 pos = stream.container.begin();
223b71206888 Initial import
thib
parents:
diff changeset
330 end = stream.container.end();
223b71206888 Initial import
thib
parents:
diff changeset
331 data = &glyph;
223b71206888 Initial import
thib
parents:
diff changeset
332
223b71206888 Initial import
thib
parents:
diff changeset
333 helper.Init(data);
223b71206888 Initial import
thib
parents:
diff changeset
334 tab_width = 0;
223b71206888 Initial import
thib
parents:
diff changeset
335 cur_y = 0;
223b71206888 Initial import
thib
parents:
diff changeset
336 int prev_y = 0;
223b71206888 Initial import
thib
parents:
diff changeset
337 int line_start = glyph.size();
223b71206888 Initial import
thib
parents:
diff changeset
338 while(pos != end) {
223b71206888 Initial import
thib
parents:
diff changeset
339 /*
223b71206888 Initial import
thib
parents:
diff changeset
340 if (pos->type == TextElem::glyph) { int c = pos->impl.Glyph.code; char cc[3]={0,0,0};cc[0]=c>>8;cc[1]=c;cout<<"glyph "<<cc<<endl;}
223b71206888 Initial import
thib
parents:
diff changeset
341 if (pos->type == TextElem::escape) { cout<<"escape "<<pos->impl.Escape.type<<endl;}
223b71206888 Initial import
thib
parents:
diff changeset
342 */
223b71206888 Initial import
thib
parents:
diff changeset
343 SetName();
223b71206888 Initial import
thib
parents:
diff changeset
344 SetLineHead();
223b71206888 Initial import
thib
parents:
diff changeset
345 MakeLine(line_start, width, lineheights);
223b71206888 Initial import
thib
parents:
diff changeset
346 if (line_start != glyph.size()) {
223b71206888 Initial import
thib
parents:
diff changeset
347 data->back().flag = TextGlyph::Flag(data->back().flag | TextGlyph::PhraseEnd | TextGlyph::LineEnd);
223b71206888 Initial import
thib
parents:
diff changeset
348 }
223b71206888 Initial import
thib
parents:
diff changeset
349 prev_y = cur_y;
223b71206888 Initial import
thib
parents:
diff changeset
350 if (pos != end && pos->type == TextElem::escape && pos->impl.Escape.type == TextElem::ret) pos++;
223b71206888 Initial import
thib
parents:
diff changeset
351 line_start = glyph.size();
223b71206888 Initial import
thib
parents:
diff changeset
352 }
223b71206888 Initial import
thib
parents:
diff changeset
353 return;
223b71206888 Initial import
thib
parents:
diff changeset
354 }
223b71206888 Initial import
thib
parents:
diff changeset
355
223b71206888 Initial import
thib
parents:
diff changeset
356 void TextHorizLayout::SetName(void) {
223b71206888 Initial import
thib
parents:
diff changeset
357 Iterator it;
223b71206888 Initial import
thib
parents:
diff changeset
358
223b71206888 Initial import
thib
parents:
diff changeset
359 tab_width = 0;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
360 /* 行頭が名前なら、処理開始 */
0
223b71206888 Initial import
thib
parents:
diff changeset
361 for (; pos != end; pos++) {
223b71206888 Initial import
thib
parents:
diff changeset
362 if (pos->type == TextElem::escape || pos->type == TextElem::glyph) break;
223b71206888 Initial import
thib
parents:
diff changeset
363 int x = 0;
223b71206888 Initial import
thib
parents:
diff changeset
364 helper.Add(x, pos, pos+1);
223b71206888 Initial import
thib
parents:
diff changeset
365 }
223b71206888 Initial import
thib
parents:
diff changeset
366
223b71206888 Initial import
thib
parents:
diff changeset
367 if (pos->type != TextElem::escape || pos->impl.Escape.type != TextElem::name_start) return;
223b71206888 Initial import
thib
parents:
diff changeset
368
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
369 /* 名前をセットし、行頭の「の分を含めてタブ幅を設定する */
0
223b71206888 Initial import
thib
parents:
diff changeset
370 pos++;
223b71206888 Initial import
thib
parents:
diff changeset
371 for (it = pos; it != end; it++) {
223b71206888 Initial import
thib
parents:
diff changeset
372 if (it->type == TextElem::escape && it->impl.Escape.type == TextElem::name_end) break;
223b71206888 Initial import
thib
parents:
diff changeset
373 }
223b71206888 Initial import
thib
parents:
diff changeset
374 if (it == end) return;
223b71206888 Initial import
thib
parents:
diff changeset
375 int line_firstpos = data->size();
223b71206888 Initial import
thib
parents:
diff changeset
376 pos = helper.Add(tab_width, pos, it);
223b71206888 Initial import
thib
parents:
diff changeset
377 pos++;
223b71206888 Initial import
thib
parents:
diff changeset
378 helper.SetGroup(data->begin() + line_firstpos, data->end());
223b71206888 Initial import
thib
parents:
diff changeset
379
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
380 // 行頭の「分を開ける
0
223b71206888 Initial import
thib
parents:
diff changeset
381 try {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
382 tab_width += helper.CharWidth(0xa1d6); /* 「 */
0
223b71206888 Initial import
thib
parents:
diff changeset
383 } catch(...) {}
223b71206888 Initial import
thib
parents:
diff changeset
384
223b71206888 Initial import
thib
parents:
diff changeset
385 return;
223b71206888 Initial import
thib
parents:
diff changeset
386 };
223b71206888 Initial import
thib
parents:
diff changeset
387
223b71206888 Initial import
thib
parents:
diff changeset
388 void TextHorizLayout::SetLineHead(void) {
223b71206888 Initial import
thib
parents:
diff changeset
389
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
390 /* 行頭は 「などか? */
0
223b71206888 Initial import
thib
parents:
diff changeset
391
223b71206888 Initial import
thib
parents:
diff changeset
392 for (; pos != end; pos++) {
223b71206888 Initial import
thib
parents:
diff changeset
393 if (pos->type == TextElem::escape || pos->type == TextElem::glyph) break;
223b71206888 Initial import
thib
parents:
diff changeset
394 int x = 0;
223b71206888 Initial import
thib
parents:
diff changeset
395 helper.Add(x, pos, pos+1);
223b71206888 Initial import
thib
parents:
diff changeset
396 }
223b71206888 Initial import
thib
parents:
diff changeset
397 if (pos->type != TextElem::glyph || Kinsoku(pos->impl.Glyph.code) != KinsokuHead) return;
223b71206888 Initial import
thib
parents:
diff changeset
398
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
399 /* 「なので、処理する */
0
223b71206888 Initial import
thib
parents:
diff changeset
400 if (tab_width != 0) tab_width -= helper.CharWidth(pos->impl.Glyph.code);
223b71206888 Initial import
thib
parents:
diff changeset
401 int line_firstpos = data->size();
223b71206888 Initial import
thib
parents:
diff changeset
402 pos = helper.Add(tab_width, pos, pos+1);
223b71206888 Initial import
thib
parents:
diff changeset
403 return;
223b71206888 Initial import
thib
parents:
diff changeset
404 }
223b71206888 Initial import
thib
parents:
diff changeset
405
223b71206888 Initial import
thib
parents:
diff changeset
406 void TextHorizLayout::MakeLine(int line_start, int width, vector<int>& lineheights) {
223b71206888 Initial import
thib
parents:
diff changeset
407
223b71206888 Initial import
thib
parents:
diff changeset
408 int x = tab_width;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
409 /* まず、全文字描画する */
0
223b71206888 Initial import
thib
parents:
diff changeset
410 while(pos != end) {
223b71206888 Initial import
thib
parents:
diff changeset
411 pos = helper.Add(x, pos, end);
223b71206888 Initial import
thib
parents:
diff changeset
412 if (pos->type == TextElem::escape && pos->impl.Escape.type == TextElem::ruby_start) {
223b71206888 Initial import
thib
parents:
diff changeset
413 pos = helper.AddRuby(x, pos, end);
223b71206888 Initial import
thib
parents:
diff changeset
414 }
223b71206888 Initial import
thib
parents:
diff changeset
415 if (pos != end && pos->type == TextElem::escape) {
223b71206888 Initial import
thib
parents:
diff changeset
416 if (pos->impl.Escape.type == TextElem::ret) break;
223b71206888 Initial import
thib
parents:
diff changeset
417 if (pos->impl.Escape.type != TextElem::ruby_start) pos++;
223b71206888 Initial import
thib
parents:
diff changeset
418 }
223b71206888 Initial import
thib
parents:
diff changeset
419 }
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
420 /* 行に分割していく */
0
223b71206888 Initial import
thib
parents:
diff changeset
421 TextGlyphStream::iterator it_start = data->begin() + line_start;
223b71206888 Initial import
thib
parents:
diff changeset
422 TextGlyphStream::iterator it_end = data->end();
223b71206888 Initial import
thib
parents:
diff changeset
423 TextGlyphStream::iterator it = it_start;
223b71206888 Initial import
thib
parents:
diff changeset
424
223b71206888 Initial import
thib
parents:
diff changeset
425 TextGlyphStream::iterator group_head = it_start;
223b71206888 Initial import
thib
parents:
diff changeset
426 int xstart = tab_width;
223b71206888 Initial import
thib
parents:
diff changeset
427 int xend = width;
223b71206888 Initial import
thib
parents:
diff changeset
428 while(it != it_end) {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
429 // この行の終わりを決める
0
223b71206888 Initial import
thib
parents:
diff changeset
430 bool is_ruby = false;
223b71206888 Initial import
thib
parents:
diff changeset
431 TextGlyphStream::iterator it_line_start = it;
223b71206888 Initial import
thib
parents:
diff changeset
432 for (; it != it_end; it++) {
223b71206888 Initial import
thib
parents:
diff changeset
433 if (it->x + it->glyph->advance.x > xend) break;
223b71206888 Initial import
thib
parents:
diff changeset
434 if (it->flag & TextGlyph::Group) is_ruby = true;
223b71206888 Initial import
thib
parents:
diff changeset
435 if (!(it->flag & TextGlyph::Group)) group_head = it;
223b71206888 Initial import
thib
parents:
diff changeset
436 }
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
437 // 水平移動の大きさを決める。デフォルトでタブ位置まで戻す
0
223b71206888 Initial import
thib
parents:
diff changeset
438 int xadd_start = -xstart + tab_width;
223b71206888 Initial import
thib
parents:
diff changeset
439 int xadd_end = xadd_start;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
440 // it == 次行の先頭なので、今行の末尾へ戻す
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
441 // ただし、 最低一文字の表示は保証
0
223b71206888 Initial import
thib
parents:
diff changeset
442 if (it != it_line_start && it != it_line_start+1 && it != it_end) it--;
223b71206888 Initial import
thib
parents:
diff changeset
443 if (it != it_end) {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
444 // グループ化されている文字で終了したら、前の文字に戻す
0
223b71206888 Initial import
thib
parents:
diff changeset
445 if (it->flag & TextGlyph::Group) it = group_head;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
446 // 次が行頭禁則文字ならこの行に入れる
0
223b71206888 Initial import
thib
parents:
diff changeset
447 if ( (it+1) != it_end && (it+1)->flag & TextGlyph::Kinsoku) it++;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
448 // 移動する大きさを決める
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
449 // 行端ぞろえ、行末文字なら半文字分だけ突き出る
0
223b71206888 Initial import
thib
parents:
diff changeset
450 int glyph_xend = it->x + it->glyph->advance.x;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
451 if (it != it_line_start && (it-1)->flag & TextGlyph::Group) { // グループ化文字の場合、1文字前も見る
0
223b71206888 Initial import
thib
parents:
diff changeset
452 if (glyph_xend < (it-1)->x + (it-1)->glyph->advance.x)
223b71206888 Initial import
thib
parents:
diff changeset
453 glyph_xend = (it-1)->x + (it-1)->glyph->advance.x;
223b71206888 Initial import
thib
parents:
diff changeset
454 }
223b71206888 Initial import
thib
parents:
diff changeset
455 xadd_end += xend - glyph_xend;
223b71206888 Initial import
thib
parents:
diff changeset
456 if (it->flag & TextGlyph::Kinsoku)
223b71206888 Initial import
thib
parents:
diff changeset
457 xadd_end += it->glyph->advance.x / 2;
223b71206888 Initial import
thib
parents:
diff changeset
458 }
223b71206888 Initial import
thib
parents:
diff changeset
459 if (it != it_end) {
223b71206888 Initial import
thib
parents:
diff changeset
460 it->flag = TextGlyph::Flag(it->flag | TextGlyph::LineEnd);
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
461 it++; // it == 次行の先頭へ
0
223b71206888 Initial import
thib
parents:
diff changeset
462 }
223b71206888 Initial import
thib
parents:
diff changeset
463 int ascent, descent;
223b71206888 Initial import
thib
parents:
diff changeset
464 helper.CalcHeight(ascent, descent, it_start, it);
223b71206888 Initial import
thib
parents:
diff changeset
465 if (ascent+descent < helper.min_lineheight) {
223b71206888 Initial import
thib
parents:
diff changeset
466 int dif = helper.min_lineheight-(ascent+descent);
223b71206888 Initial import
thib
parents:
diff changeset
467 ascent += dif/2;
223b71206888 Initial import
thib
parents:
diff changeset
468 descent += dif-(dif/2);
223b71206888 Initial import
thib
parents:
diff changeset
469 }
223b71206888 Initial import
thib
parents:
diff changeset
470 if (is_ruby) ascent+=ruby_lineskip;
223b71206888 Initial import
thib
parents:
diff changeset
471 helper.AdjustPosition(xadd_start, xadd_end, cur_y+ascent+1, it_start, it);
223b71206888 Initial import
thib
parents:
diff changeset
472 cur_y += ascent + descent + line_skip;
223b71206888 Initial import
thib
parents:
diff changeset
473 lineheights.push_back(ascent+descent+line_skip);
223b71206888 Initial import
thib
parents:
diff changeset
474
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
475 /* 次の行へ */
0
223b71206888 Initial import
thib
parents:
diff changeset
476 if (it != it_end) {
223b71206888 Initial import
thib
parents:
diff changeset
477 it_start = it;
223b71206888 Initial import
thib
parents:
diff changeset
478 group_head = it_start;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
479 /* 1文字目がグループ化されていれば、グループの先頭文字にする */
0
223b71206888 Initial import
thib
parents:
diff changeset
480 xstart = it->x;
223b71206888 Initial import
thib
parents:
diff changeset
481 if (it->flag & TextGlyph::Group) {
223b71206888 Initial import
thib
parents:
diff changeset
482 TextGlyphStream::iterator jit;
223b71206888 Initial import
thib
parents:
diff changeset
483 for (jit = it; jit != it_end; jit++) {
223b71206888 Initial import
thib
parents:
diff changeset
484 if (xstart > jit->x) xstart = jit->x;
223b71206888 Initial import
thib
parents:
diff changeset
485 if (!(jit->flag & TextGlyph::Group)) break;
223b71206888 Initial import
thib
parents:
diff changeset
486 }
223b71206888 Initial import
thib
parents:
diff changeset
487 }
223b71206888 Initial import
thib
parents:
diff changeset
488 xend = it->x + width-tab_width;
223b71206888 Initial import
thib
parents:
diff changeset
489 }
223b71206888 Initial import
thib
parents:
diff changeset
490 }
223b71206888 Initial import
thib
parents:
diff changeset
491 return;
223b71206888 Initial import
thib
parents:
diff changeset
492 }
223b71206888 Initial import
thib
parents:
diff changeset
493
223b71206888 Initial import
thib
parents:
diff changeset
494 namespace XKFont {
223b71206888 Initial import
thib
parents:
diff changeset
495
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
496 HorizLayout::HorizLayout(const char* fontname, int size) {
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
497 font = new Font(fontname, size);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
498 pimpl = new ::TextHorizLayout(font);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
499 }
0
223b71206888 Initial import
thib
parents:
diff changeset
500
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
501 HorizLayout::~HorizLayout() {
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
502 delete pimpl;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
503 delete font;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
504 }
0
223b71206888 Initial import
thib
parents:
diff changeset
505
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
506 void HorizLayout::Layout(TextStream& stream, TextGlyphStream& glyph, vector<int>& lineheights, int width) {
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
507 pimpl->Layout(stream, glyph, lineheights, width);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
508 };
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
509
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
510 TextGlyphStream HorizLayout::Layout(const char* str, int width, int r, int gc, int b) {
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
511 TextStream s;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
512 s.SetColor(r,gc,b);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
513 s.Add(str);
53
ddbcbd000206 * MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents: 52
diff changeset
514 return Layout(s, width);
ddbcbd000206 * MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents: 52
diff changeset
515 }
ddbcbd000206 * MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents: 52
diff changeset
516
ddbcbd000206 * MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents: 52
diff changeset
517 TextGlyphStream HorizLayout::Layout(TextStream s, int width) {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
518 TextGlyphStream g;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
519 vector<int> h;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
520 Layout(s, g, h, width);
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
521 return g;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 50
diff changeset
522 }
0
223b71206888 Initial import
thib
parents:
diff changeset
523
223b71206888 Initial import
thib
parents:
diff changeset
524 };
223b71206888 Initial import
thib
parents:
diff changeset
525
223b71206888 Initial import
thib
parents:
diff changeset
526 int TextGlyphStream::width(void) {
223b71206888 Initial import
thib
parents:
diff changeset
527 if (empty()) return 0;
223b71206888 Initial import
thib
parents:
diff changeset
528 iterator it;
223b71206888 Initial import
thib
parents:
diff changeset
529 int xmax = 0;
223b71206888 Initial import
thib
parents:
diff changeset
530 for (it=begin(); it!=end(); it++) {
223b71206888 Initial import
thib
parents:
diff changeset
531 int x = it->x + it->glyph->advance.x;
223b71206888 Initial import
thib
parents:
diff changeset
532 if (x > xmax) xmax = x;
223b71206888 Initial import
thib
parents:
diff changeset
533 }
223b71206888 Initial import
thib
parents:
diff changeset
534 return xmax + 1;
223b71206888 Initial import
thib
parents:
diff changeset
535 }
223b71206888 Initial import
thib
parents:
diff changeset
536
223b71206888 Initial import
thib
parents:
diff changeset
537 int TextGlyphStream::height(void) {
223b71206888 Initial import
thib
parents:
diff changeset
538 if (empty()) return 0;
223b71206888 Initial import
thib
parents:
diff changeset
539 iterator it;
223b71206888 Initial import
thib
parents:
diff changeset
540 int ymax = 0;
223b71206888 Initial import
thib
parents:
diff changeset
541 it = end();
223b71206888 Initial import
thib
parents:
diff changeset
542 while(1) {
223b71206888 Initial import
thib
parents:
diff changeset
543 it--;
223b71206888 Initial import
thib
parents:
diff changeset
544 int y = it->y + it->glyph->bitmap.rows - it->glyph->bitmap_top;
223b71206888 Initial import
thib
parents:
diff changeset
545 if (ymax < y) ymax = y;
223b71206888 Initial import
thib
parents:
diff changeset
546 if (it == begin()) break;
223b71206888 Initial import
thib
parents:
diff changeset
547 if (it->flag & TextGlyph::LineEnd) {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 53
diff changeset
548 if (!(it->flag & TextGlyph::PhraseEnd)) break; // PhraseEnd は最後の文字
0
223b71206888 Initial import
thib
parents:
diff changeset
549 }
223b71206888 Initial import
thib
parents:
diff changeset
550 }
223b71206888 Initial import
thib
parents:
diff changeset
551 return ymax + 1;
223b71206888 Initial import
thib
parents:
diff changeset
552 }
223b71206888 Initial import
thib
parents:
diff changeset
553