• R/O
  • HTTP
  • SSH
  • HTTPS

TinyBannavi: Commit

タイニー番組ナビゲータ本体


Commit MetaInfo

Revisiónced3b269c222d4bb9abb8fc10d28e2fea836c022 (tree)
Tiempo2013-12-18 22:03:54
Autorpeeweedee <peeweedee@user...>
Commiterpeeweedee

Log Message

新聞形式の描画速度向上施策

Cambiar Resumen

Diferencia incremental

--- a/TinyBannavi/05_history.txt
+++ b/TinyBannavi/05_history.txt
@@ -10,9 +10,13 @@
1010 2chの番ナビスレ:http://toro.2ch.net/test/read.cgi/av/1352223253/
1111 ★☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆★
1212
13-3.22.10β+1.5.12(2013-12-18)
13+3.22.12β+1.5.12(2013-12-XX)
1414 ■変更点
15- ・(番組追跡) 処理の効率化
15+ ・(新聞形式)番組枠内テキストの描画を、LineBreakMeasurerからdrawGlyphVectorに変更。それに伴い番組詳細の描画行数制限を廃止
16+
17+3.22.11β+1.5.12(2013-12-18)
18+■変更点
19+ ・(番組追跡)処理の効率化
1620 ■バグ修正
1721  ・(Web番組表[スカパー]) 1日の番組表が複数ページにまたがる場合に対応していない問題を修正(>>645.)
1822  ・(ステータスビュー) りもこんと同じ修正(>>640.)
--- a/TinyBannavi/src/tainavi/AbsPaperColorsDialog.java
+++ b/TinyBannavi/src/tainavi/AbsPaperColorsDialog.java
@@ -139,7 +139,6 @@ abstract class AbsPaperColorsDialog extends JEscCancelDialog {
139139 private JCCLabel jLabel_titleFontColor = null;
140140 private JScrollPane jScrollPane_titleFontStyle = null;
141141 private JCheckBoxPanel jCBP_showDetail = null;
142- private JSliderPanel jSP_detailRows = null;
143142 private JComboBoxPanel jCBX_detailFont = null;
144143 private JSliderPanel jSP_detailFontSize = null;
145144 private JCCLabel jLabel_detailFontColor = null;
@@ -286,7 +285,6 @@ abstract class AbsPaperColorsDialog extends JEscCancelDialog {
286285 to.setTitleFontColor(jLabel_titleFontColor.getChoosed());
287286 to.setTitleFontStyle(getFontStyles((JNETable) jScrollPane_titleFontStyle.getViewport().getView()));
288287 to.setShowDetail(jCBP_showDetail.isSelected());
289- to.setDetailRows(jSP_detailRows.getValue());
290288 to.setDetailFont((String) jCBX_detailFont.getSelectedItem());
291289 to.setDetailFontSize(jSP_detailFontSize.getValue());
292290 to.setDetailFontColor(jLabel_detailFontColor.getChoosed());
@@ -586,9 +584,6 @@ abstract class AbsPaperColorsDialog extends JEscCancelDialog {
586584 CommonSwingUtils.putComponentOn(jPanel_fonts, jCBP_showDetail = new JCheckBoxPanel("表示する",LABEL_WIDTH), TITLE_WIDTH+ITEM_WIDTH, PARTS_HEIGHT, SEP_WIDTH, y);
587585
588586 y += (PARTS_HEIGHT+SEP_HEIGHT_NARROW);
589- CommonSwingUtils.putComponentOn(jPanel_fonts, jSP_detailRows = new JSliderPanel("最大行数",LABEL_WIDTH,1,50,ITEM_WIDTH), TITLE_WIDTH+ITEM_WIDTH, PARTS_HEIGHT, SEP_WIDTH, y);
590-
591- y += (PARTS_HEIGHT+SEP_HEIGHT_NARROW);
592587 CommonSwingUtils.putComponentOn(jPanel_fonts, jCBX_detailFont = new JComboBoxPanel("フォント",LABEL_WIDTH,ITEM_WIDTH,true), LABEL_WIDTH+ITEM_WIDTH, PARTS_HEIGHT, SEP_WIDTH, y);
593588
594589 y += (PARTS_HEIGHT+SEP_HEIGHT_NARROW);
@@ -628,7 +623,6 @@ abstract class AbsPaperColorsDialog extends JEscCancelDialog {
628623 setFontStyles((JNETable) jScrollPane_titleFontStyle.getViewport().getView(), origenv.getTitleFontStyle());
629624 //
630625 jCBP_showDetail.setSelected(origenv.getShowDetail());
631- jSP_detailRows.setValue(origenv.getDetailRows());
632626 if ( ! origenv.getDetailFont().equals("") ) {
633627 jCBX_detailFont.setSelectedItem(origenv.getDetailFont());
634628 }
--- a/TinyBannavi/src/tainavi/AbsPaperView.java
+++ b/TinyBannavi/src/tainavi/AbsPaperView.java
@@ -2512,7 +2512,6 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
25122512 JTXTButton.setSplitEpno(ec.getSplitEpno());
25132513 JTXTButton.setShowDetail(ec.getShowDetail());
25142514 JTXTButton.setDetailTab(ec.getDetailTab());
2515- JTXTButton.setDetailRows(ec.getDetailRows());
25162515
25172516 JTXTButton.setTitleFont(ec.getTitleFont());
25182517 JTXTButton.setTitleFontStyle(ec.getTitleFontStyle());
--- a/TinyBannavi/src/tainavi/JTXTButton.java
+++ b/TinyBannavi/src/tainavi/JTXTButton.java
@@ -4,17 +4,20 @@ import java.awt.AlphaComposite;
44 import java.awt.Color;
55 import java.awt.Dimension;
66 import java.awt.Font;
7+import java.awt.FontMetrics;
78 import java.awt.Graphics;
89 import java.awt.Graphics2D;
10+import java.awt.Rectangle;
911 import java.awt.RenderingHints;
1012 import java.awt.font.FontRenderContext;
11-import java.awt.font.LineBreakMeasurer;
13+import java.awt.font.GlyphMetrics;
14+import java.awt.font.GlyphVector;
1215 import java.awt.font.TextAttribute;
13-import java.awt.font.TextLayout;
16+import java.awt.geom.Point2D;
1417 import java.awt.image.BufferedImage;
15-import java.text.AttributedCharacterIterator;
16-import java.text.AttributedString;
1718 import java.util.ArrayList;
19+import java.util.HashMap;
20+import java.util.Map;
1821
1922 import javax.swing.JButton;
2023 import javax.swing.JLabel;
@@ -32,8 +35,8 @@ public class JTXTButton extends JLabel {
3235 * フォントスタイル
3336 */
3437 public static enum FontStyle {
35- BOLD ("太字"),
36- ITALIC ("斜体"),
38+ BOLD ("太字"),
39+ ITALIC ("斜体"),
3740 UNDERLINE ("下線");
3841
3942 private String name;
@@ -85,24 +88,27 @@ public class JTXTButton extends JLabel {
8588 private static boolean splitEpno = false;
8689 private static boolean showDetail = true;
8790 private static float detailTab = 2.0F;
88- private static int detailRows = 3;
8991
9092 private static Font defaultFont = new JLabel().getFont();
93+
9194 private static Font titleFont = defaultFont;
9295 private static int titleFontSize = defaultFont.getSize();
9396 private static Color titleFontColor = Color.BLUE;
9497 private static int titleFontStyle = Font.BOLD;
95- private static boolean titleFontUL = true;
98+
9699 private static Font detailFont = defaultFont;
97100 private static int detailFontSize = defaultFont.getSize();
98101 private static Color detailFontColor = Color.DARK_GRAY;
99102 private static int detailFontStyle = defaultFont.getStyle();
100- private static boolean detailFontUL = false;
101- private static Object aahint = RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
103+
104+ private static Font startFont = defaultFont;
105+
106+ private static FontRenderContext frc = new FontRenderContext(null, RenderingHints.VALUE_TEXT_ANTIALIAS_ON, RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT);
102107
103108 private static int columnWidth = 0;
104109 private static float heightMultiplier = 0;
105110
111+
106112 /*******************************************************************************
107113 * コンストラクタ
108114 ******************************************************************************/
@@ -189,9 +195,6 @@ public class JTXTButton extends JLabel {
189195 public static void setDetailTab(float n) {
190196 detailTab = n;
191197 }
192- public static void setDetailRows(int n) {
193- detailRows = n;
194- }
195198
196199 // フォントスタイル
197200 public static void setTitleFont(String fn) {
@@ -216,6 +219,7 @@ public class JTXTButton extends JLabel {
216219 Font f = new Font(fn,detailFontStyle,detailFontSize);
217220 if ( f != null ) {
218221 detailFont = f;
222+ startFont = f.deriveFont(Font.BOLD);
219223 return;
220224 }
221225 }
@@ -224,6 +228,7 @@ public class JTXTButton extends JLabel {
224228 public static void setDetailFontSize(int n) {
225229 detailFontSize = n;
226230 detailFont = detailFont.deriveFont((float)detailFontSize);
231+ startFont = startFont.deriveFont((float)detailFontSize);
227232 }
228233 public static void setDetailFontColor(Color c) {
229234 detailFontColor = c;
@@ -231,40 +236,37 @@ public class JTXTButton extends JLabel {
231236
232237 // フォントスタイルの変更
233238 public static void setTitleFontStyle(ArrayList<FontStyle> fsa) {
234- setTmpFontStyle(fsa);
235- titleFontStyle = tmpFontStyle;
236- titleFontUL = tmpFontUL;
237- titleFont = titleFont.deriveFont((titleFont.getStyle() & ~(Font.BOLD|Font.ITALIC)) | titleFontStyle);
239+ titleFont = setFontStyle(titleFont, (float)titleFontSize, fsa);
238240 }
239241 public static void setDetailFontStyle(ArrayList<FontStyle> fsa) {
240- setTmpFontStyle(fsa);
241- detailFontStyle = tmpFontStyle;
242- detailFontUL = tmpFontUL;
243- detailFont = detailFont.deriveFont((detailFont.getStyle() & ~(Font.BOLD|Font.ITALIC)) | detailFontStyle);
242+ detailFont = setFontStyle(detailFont, (float)detailFontSize, fsa);
244243 }
245- private static void setTmpFontStyle(ArrayList<FontStyle> fsa) {
246- tmpFontStyle = 0;
247- tmpFontUL = false;
244+
245+ private static Font setFontStyle(Font f, float size, ArrayList<FontStyle> fsa) {
246+ Map<TextAttribute, Object> attributes = new HashMap<TextAttribute, Object>();
247+ attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
248+ attributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
249+ attributes.remove(TextAttribute.UNDERLINE);
248250 for ( FontStyle fs : fsa ) {
249251 switch (fs) {
250252 case BOLD:
251- tmpFontStyle |= Font.BOLD;
253+ attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
252254 break;
253255 case ITALIC:
254- tmpFontStyle |= Font.ITALIC;
256+ attributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
255257 break;
256258 case UNDERLINE:
257- tmpFontUL = true;
259+ attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);//LOW_ONE_PIXEL);
258260 break;
259261 }
260262 }
263+ attributes.put(TextAttribute.SIZE, size);
264+ return f.deriveFont(attributes);
261265 }
262- private static int tmpFontStyle;
263- private static boolean tmpFontUL;
264266
265267 // フォントエイリアスの変更
266268 public static void setAAHint(Object o) {
267- aahint = o;
269+ frc = new FontRenderContext(null, o, RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT);
268270 }
269271
270272
@@ -289,12 +291,10 @@ public class JTXTButton extends JLabel {
289291
290292 float draww = (float)imgw-DRAWTAB*2.0F;
291293 float drawh = (float)imgh;
292- float detailw = draww-detailTab;
293294
294295 image = new BufferedImage(imgw, imgh, BufferedImage.TYPE_INT_ARGB);
295296 Graphics2D g2 = (Graphics2D)image.createGraphics();
296297
297- g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,aahint); // アンチエイリアスの設定
298298 g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_SPEED);
299299 g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
300300
@@ -302,31 +302,41 @@ public class JTXTButton extends JLabel {
302302
303303 // 開始時刻と延長警告の描画
304304 if (showStart && tvd.start != null && tvd.start.length() > 0) {
305- //
306- Font fs = detailFont;
307- String sStr = tvd.start+" "+tvd.extension_mark;
308- //
309- Font f = fs.deriveFont(fs.getStyle() | Font.BOLD);
310- AttributedString as = new AttributedString(sStr);
311- as.addAttribute(TextAttribute.FONT, f);
312- as.addAttribute(TextAttribute.FOREGROUND, Color.BLACK, 0, 5);
313- if (sStr.length() > 6) {
314- as.addAttribute(TextAttribute.FOREGROUND, Color.RED, 6, sStr.length());
305+ FontMetrics fm = g2.getFontMetrics(startFont);
306+ float hi = Float.valueOf(fm.getHeight());
307+ float as = Float.valueOf(fm.getAscent());
308+
309+ float startx = Float.valueOf(DRAWTAB);
310+ float startw = draww;
311+ float xposstartx = 0.0F;
312+
313+ baseline = as; // 初期垂直位置
314+
315+ {
316+ WrappedGlyphVector wgv = getWrappedGlyphVector(tvd.start, startw, xposstartx, startFont, as, frc);
317+ GlyphVector gv = wgv.getGv();
318+ g2.setPaint(Color.BLACK);
319+ g2.drawGlyphVector(gv, startx, baseline);
320+
321+ xposstartx = wgv.getLastX(); // 後続有り
322+ baseline += wgv.getLastY();
315323 }
316- AttributedCharacterIterator ac = as.getIterator();
317- FontRenderContext fc = g2.getFontRenderContext();
318- LineBreakMeasurer m = new LineBreakMeasurer(ac,fc);
319- while ( m.getPosition() < sStr.length() ) {
320- TextLayout tl = m.nextLayout(draww);
321- baseline += tl.getAscent();
322- tl.draw(g2, DRAWTAB, baseline);
323- baseline += tl.getDescent() + tl.getLeading();
324+
325+ {
326+ WrappedGlyphVector wgv = getWrappedGlyphVector(" "+tvd.extension_mark, startw, xposstartx, startFont, as, frc);
327+ GlyphVector gv = wgv.getGv();
328+ g2.setPaint(Color.RED);
329+ g2.drawGlyphVector(gv, startx, baseline);
330+
331+ baseline += wgv.getLastY();
324332 }
333+
334+ baseline += hi;
325335 }
326336
327337 // タイトルの描画
328338 String title = ( splitEpno ) ? tvd.splitted_title : tvd.title;
329- if (title.length() > 0) {
339+ if ( title.length() > 0 ) {
330340 //
331341 String aMark;
332342 if (showStart && tvd.start.length() > 0) {
@@ -340,28 +350,40 @@ public class JTXTButton extends JLabel {
340350 aMark = tvd.prefix_mark + tvd.newlast_mark;
341351 }
342352 }
343- String tStr = aMark+title+tvd.postfix_mark;
344- //
345- AttributedString as = new AttributedString(tStr);
346- as.addAttribute(TextAttribute.FONT, titleFont);
347- {
348- if (titleFontUL) {
349- as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_ONE_PIXEL, aMark.length(), aMark.length()+title.length());
350- }
351- as.addAttribute(TextAttribute.FOREGROUND, titleFontColor, aMark.length(), tStr.length());
352- if (aMark.length() > 0) {
353- as.addAttribute(TextAttribute.FOREGROUND, Color.RED, 0, aMark.length());
354- }
353+
354+ FontMetrics fm = g2.getFontMetrics(titleFont);
355+ float hi = Float.valueOf(fm.getHeight());
356+ float as = Float.valueOf(fm.getAscent());
357+
358+ float titlex = Float.valueOf(DRAWTAB);
359+ float titlew = draww;
360+ float xpos = 0.0F;
361+
362+ if ( baseline == 0.0F ) {
363+ baseline = as; // 初期垂直位置
355364 }
356- AttributedCharacterIterator ac = as.getIterator();
357- FontRenderContext fc = g2.getFontRenderContext();
358- LineBreakMeasurer m = new LineBreakMeasurer(ac,fc);
359- while (m.getPosition() < tStr.length()) {
360- TextLayout tl = m.nextLayout(draww);
361- baseline += tl.getAscent();
362- tl.draw(g2, DRAWTAB, baseline);
363- baseline += tl.getDescent() + tl.getLeading();
365+
366+ if ( aMark.length() > 0 ) {
367+ WrappedGlyphVector wgv = getWrappedGlyphVector(aMark, titlew, xpos, titleFont, as, frc);
368+ GlyphVector gv = wgv.getGv();
369+ g2.setPaint(Color.RED);
370+ g2.drawGlyphVector(gv, titlex, baseline);
371+
372+ xpos = wgv.getLastX(); // 後続有り
373+ baseline += wgv.getLastY();
364374 }
375+
376+ {
377+ WrappedGlyphVector wgv = getWrappedGlyphVector(title+tvd.postfix_mark, titlew, xpos, titleFont, as, frc);
378+ GlyphVector gv = wgv.getGv();
379+ g2.setPaint(titleFontColor);
380+
381+ drawString(g2, wgv, titlex, baseline);
382+
383+ baseline += wgv.getLastY();
384+ }
385+
386+ baseline += hi;
365387 }
366388
367389 // 番組詳細の描画
@@ -373,27 +395,109 @@ public class JTXTButton extends JLabel {
373395 else {
374396 detail = tvd.detail;
375397 }
376- if ( detail.length() > 0 ) {
377- AttributedString as = new AttributedString(detail);
378- as.addAttribute(TextAttribute.FONT, detailFont);
379- if (detailFontUL) {
380- as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_ONE_PIXEL);
381- }
382- as.addAttribute(TextAttribute.FOREGROUND, detailFontColor);
383- AttributedCharacterIterator ac = as.getIterator();
384- FontRenderContext fc = g2.getFontRenderContext();
385- LineBreakMeasurer m = new LineBreakMeasurer(ac,fc);
386- for ( int row=0; m.getPosition()<detail.length() && baseline<=drawh && (detailRows>0 && row<detailRows); row++ ) {
387- TextLayout tl = m.nextLayout(detailw);
388- baseline += tl.getAscent();
389- tl.draw(g2, (DRAWTAB+detailTab), baseline);
390- baseline += tl.getDescent() + tl.getLeading();
391- }
398+
399+ FontMetrics fm = g2.getFontMetrics(detailFont);
400+ float as = Float.valueOf(fm.getAscent());
401+ float detailx = Float.valueOf(DRAWTAB+detailTab);
402+ float detailw = draww-detailTab;
403+
404+ if ( baseline == 0.0F ) {
405+ baseline = as; // 初期垂直位置
392406 }
407+
408+ WrappedGlyphVector wgv = getWrappedGlyphVector(detail, detailw, 0.0f, detailFont, as, frc);
409+ g2.setPaint(detailFontColor);
410+
411+ drawString(g2, wgv, detailx, baseline);
393412 }
394413 }
395414
396415 // 反映
397416 g.drawImage(image, 0, 0, this);
398417 }
418+
419+ /**
420+ *
421+ */
422+ private void drawString(Graphics2D g2, WrappedGlyphVector wgv, float x, float y) {
423+ g2.drawGlyphVector(wgv.getGv(), x, y);
424+
425+ if ( wgv.getGv().getFont().getAttributes().get(TextAttribute.UNDERLINE) != null ) {
426+ for ( Rectangle r : wgv.getLinePositions() ) {
427+ g2.drawLine((int)x+r.x, (int)y+r.y+1, (int)x+r.x+r.width-1, (int)y+r.y+1);
428+ }
429+ }
430+ }
431+
432+ /**
433+ * 参考:てんぷらメモ/JTableのセル幅で文字列を折り返し ( http://terai.xrea.jp/Swing/TableCellRenderer.html )
434+ * @param str 描画する文字列
435+ * @param width 描画領域の幅
436+ * @param height 描画領域の高さ
437+ * @param xstart 1行目の描画開始位置
438+ * @param lineCountMax 最大描画行数
439+ * @param font 描画フォント
440+ * @param lineHeight 1行あたりの高さ
441+ * @param frc FontRenderContext
442+ * @return
443+ */
444+ private WrappedGlyphVector getWrappedGlyphVector(String str, float width, float xstart, Font font, float lineHeight, FontRenderContext frc) {
445+ Point2D gmPos = new Point2D.Double(0.0d, 0.0d);
446+ GlyphVector gv = font.createGlyphVector(frc, str);
447+ WrappedGlyphVector wgv = new WrappedGlyphVector(gv);
448+ float xpos = xstart;
449+ float ypos = 0.0F;
450+ float advance = 0.0F;
451+ GlyphMetrics gm;
452+ for( int i=0; i <= gv.getNumGlyphs(); i++ ) {
453+ if ( i == gv.getNumGlyphs() ) {
454+ int x = (int) ((ypos == 0.0F) ? xstart : 0.0F);
455+ int y = (int) ypos;
456+ int w = (int) (xpos - x);
457+ wgv.addLinePosition(new Rectangle(x, y, w, 1));
458+ break;
459+ }
460+ gm = gv.getGlyphMetrics(i);
461+ advance = gm.getAdvance();
462+ if( xpos < width && width <= xpos+advance ) {
463+ int x = (int) ((ypos == 0.0F) ? xstart : 0.0F);
464+ int y = (int) ypos;
465+ int w = (int) (xpos - x);
466+ wgv.addLinePosition(new Rectangle(x, y, w, 1));
467+ ypos += lineHeight;
468+ xpos = 0.0f;
469+ }
470+ gmPos.setLocation(xpos, ypos);
471+ gv.setGlyphPosition(i, gmPos);
472+ xpos = xpos + advance;
473+
474+ wgv.setLastX(xpos);
475+ wgv.setLastY(ypos);
476+ }
477+ return wgv;
478+ }
479+
480+ private class WrappedGlyphVector {
481+
482+ public WrappedGlyphVector(GlyphVector gv) {
483+ super();
484+ this.gv = gv;
485+ }
486+
487+ private GlyphVector gv;
488+
489+ public GlyphVector getGv() { return gv; }
490+
491+ private float lastx;
492+ private float lasty;
493+
494+ public void setLastX(float x) { lastx = x; }
495+ public float getLastX() { return lastx; }
496+ public void setLastY(float y) { lasty = y; }
497+ public float getLastY() { return lasty; }
498+
499+ private ArrayList<Rectangle> linePositions = new ArrayList<Rectangle>();
500+ public ArrayList<Rectangle> getLinePositions() { return linePositions; }
501+ public void addLinePosition(Rectangle r) { linePositions.add(r); }
502+ }
399503 }
--- a/TinyBannavi/src/tainavi/TraceProgram.java
+++ b/TinyBannavi/src/tainavi/TraceProgram.java
@@ -107,8 +107,8 @@ public class TraceProgram {
107107
108108 /**
109109 * 2つの文字を比較してスコアを計算する(special thanks to ◆kzz0PzTAMM)
110- * @param searchkey 番組追跡の検索キー
111- * @param target タイトル(中の文字がsearchkeyに何個含まれているかを確認する)
110+ * @param searchkey 番組追跡の検索キーワード(「検索キーワード」の成分が「番組表のタイトルにどれくらい含まれているかを判定する」)
111+ * @param target 番組表のタイトル
112112 * @return
113113 */
114114 public static int sumScore(String searchkey, String target)
@@ -134,7 +134,6 @@ public class TraceProgram {
134134 }
135135 else {
136136 if ( target.indexOf(searchkey) != -1 ) {
137- System.err.println("xxxx "+target+", "+searchkey);
138137 return 100;
139138 }
140139 }
Show on old repository browser