1 /*$
2 Copyright (C) 2016-2020 Azel.
3
4 This file is part of AzPainterB.
5
6 AzPainterB is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 AzPainterB is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 $*/
19
20 /*****************************************
21 * mPixbuf への描画関数
22 *****************************************/
23
24 #include <math.h>
25
26 #include "mDef.h"
27 #include "mPixbuf.h"
28 #include "mSysCol.h"
29 #include "mRectBox.h"
30
31 #include "defCanvasInfo.h"
32
33
34
35
36 //===========================
37 // sub
38 //===========================
39
40
41 /** クリッピング付き直線描画 (blend A=0-128) */
42
43 /* クリッピング範囲が異なっても、常に同じ位置に点が打たれるようにする。
44 * でないと、キャンバス全体を更新した時と描画時に範囲更新した時とで
45 * グリッドの線がずれる場合がある。 */
46
_drawline_blend_clip(mPixbuf * p,int x1,int y1,int x2,int y2,uint32_t col,mRect * rc)47 static void _drawline_blend_clip(mPixbuf *p,int x1,int y1,int x2,int y2,uint32_t col,
48 mRect *rc)
49 {
50 int dx,dy,tmp;
51 int64_t f,inc;
52 mRect rcb;
53
54 //線からなる矩形が範囲外か
55
56 if(x1 < x2)
57 rcb.x1 = x1, rcb.x2 = x2;
58 else
59 rcb.x1 = x2, rcb.x2 = x1;
60
61 if(y1 < y2)
62 rcb.y1 = y1, rcb.y2 = y2;
63 else
64 rcb.y1 = y2, rcb.y2 = y1;
65
66 if(rcb.x2 < rc->x1 || rcb.x1 > rc->x2 || rcb.y2 < rc->y1 || rcb.y1 > rc->y2)
67 return;
68
69 //
70
71 if(x1 == x2 && y1 == y2)
72 {
73 //1px
74
75 mPixbufSetPixel_blend128(p, x1, y1, col);
76 }
77 else if(y1 == y2)
78 {
79 //横線
80
81 x1 = rcb.x1, x2 = rcb.x2;
82
83 if(x1 < rc->x1) x1 = rc->x1;
84 if(x2 > rc->x2) x2 = rc->x2;
85
86 mPixbufLineH_blend(p, x1, y1, x2 - x1 + 1, col, (col >> 24) << 1); //A=0-256
87 }
88 else if(x1 == x2)
89 {
90 //縦線
91
92 y1 = rcb.y1, y2 = rcb.y2;
93
94 if(y1 < rc->y1) y1 = rc->y1;
95 if(y2 > rc->y2) y2 = rc->y2;
96
97 mPixbufLineV_blend(p, x1, y1, y2 - y1 + 1, col, (col >> 24) << 1);
98 }
99 else
100 {
101 //直線
102
103 dx = rcb.x2 - rcb.x1;
104 dy = rcb.y2 - rcb.y1;
105
106 if(dx > dy)
107 {
108 //----- 横長
109
110 //x1 -> x2 の方向にする
111
112 if(x1 > x2)
113 {
114 x1 = rcb.x1, x2 = rcb.x2;
115 tmp = y1, y1 = y2, y2 = tmp;
116 }
117
118 inc = ((int64_t)(y2 - y1) << 16) / dx;
119 f = (int64_t)y1 << 16;
120
121 //X クリッピング
122
123 if(x1 < rc->x1)
124 {
125 f += inc * (rc->x1 - x1);
126 x1 = rc->x1;
127 }
128
129 if(x2 > rc->x2) x2 = rc->x2;
130
131 //
132
133 tmp = (f + (1<<15)) >> 16;
134
135 if(y1 < y2)
136 {
137 //----- Y が下方向
138
139 //開始位置が範囲外
140
141 if(tmp > rc->y2) return;
142
143 //範囲内まで進める
144
145 while(tmp < rc->y1)
146 {
147 x1++;
148 f += inc;
149
150 tmp = (f + (1<<15)) >> 16;
151 }
152
153 //描画
154
155 for(; x1 <= x2; x1++, f += inc)
156 {
157 tmp = (f + (1<<15)) >> 16;
158 if(tmp > rc->y2) break;
159
160 mPixbufSetPixel_blend128(p, x1, tmp, col);
161 }
162 }
163 else
164 {
165 //----- Y が上方向
166
167 //開始位置が範囲外
168
169 if(tmp < rc->y1) return;
170
171 //範囲内まで進める
172
173 while(tmp > rc->y2)
174 {
175 x1++;
176 f += inc;
177
178 tmp = (f + (1<<15)) >> 16;
179 }
180
181 //描画
182
183 for(; x1 <= x2; x1++, f += inc)
184 {
185 tmp = (f + (1<<15)) >> 16;
186 if(tmp < rc->y1) break;
187
188 mPixbufSetPixel_blend128(p, x1, tmp, col);
189 }
190 }
191 }
192 else
193 {
194 //------ 縦長
195
196 //y1 -> y2 の方向にする
197
198 if(y1 > y2)
199 {
200 y1 = rcb.y1, y2 = rcb.y2;
201 tmp = x1, x1 = x2, x2 = tmp;
202 }
203
204 inc = ((int64_t)(x2 - x1) << 16) / dy;
205 f = (int64_t)x1 << 16;
206
207 //Y クリッピング
208
209 if(y1 < rc->y1)
210 {
211 f += inc * (rc->y1 - y1);
212 y1 = rc->y1;
213 }
214
215 if(y2 > rc->y2) y2 = rc->y2;
216
217 //
218
219 tmp = (f + (1<<15)) >> 16;
220
221 if(x1 < x2)
222 {
223 //----- X が右方向
224
225 //開始位置が範囲外
226
227 if(tmp > rc->x2) return;
228
229 //範囲内まで進める
230
231 while(tmp < rc->x1)
232 {
233 y1++;
234 f += inc;
235
236 tmp = (f + (1<<15)) >> 16;
237 }
238
239 //描画
240
241 for(; y1 <= y2; y1++, f += inc)
242 {
243 tmp = (f + (1<<15)) >> 16;
244 if(tmp > rc->x2) break;
245
246 mPixbufSetPixel_blend128(p, tmp, y1, col);
247 }
248 }
249 else
250 {
251 //----- X が左方向
252
253 //開始位置が範囲外
254
255 if(tmp < rc->x1) return;
256
257 //範囲内まで進める
258
259 while(tmp > rc->x2)
260 {
261 y1++;
262 f += inc;
263
264 tmp = (f + (1<<15)) >> 16;
265 }
266
267 //描画
268
269 for(; y1 <= y2; y1++, f += inc)
270 {
271 tmp = (f + (1<<15)) >> 16;
272 if(tmp < rc->x1) break;
273
274 mPixbufSetPixel_blend128(p, tmp, y1, col);
275 }
276 }
277 }
278 }
279 }
280
281 /** クリッピング付き破線直線描画
282 *
283 * @return (x2,y2) の位置のパターン番号 */
284
_drawline_dash_clip(mPixbuf * p,int x1,int y1,int x2,int y2,int pat,mRect * rcclip)285 static int _drawline_dash_clip(mPixbuf *p,int x1,int y1,int x2,int y2,int pat,mRect *rcclip)
286 {
287 int dx,dy,tmp,pat_end,dir;
288 int64_t f,inc;
289 mPoint min,max;
290 mPixCol col[4];
291 uint8_t *pd;
292
293 col[0] = col[1] = 0;
294 col[2] = col[3] = MSYSCOL(WHITE);
295
296 //描画座標の最小、最大値
297
298 if(x1 < x2)
299 min.x = x1, max.x = x2;
300 else
301 min.x = x2, max.x = x1;
302
303 if(y1 < y2)
304 min.y = y1, max.y = y2;
305 else
306 min.y = y2, max.y = y1;
307
308 //
309
310 if(x1 == x2 && y1 == y2)
311 {
312 //====== 1px
313
314 if(rcclip->x1 <= x1 && x1 <= rcclip->x2 && rcclip->y1 <= y1 && y1 <= rcclip->y2)
315 mPixbufSetPixel(p, x1, y1, col[pat]);
316
317 return pat;
318 }
319 else if(y1 == y2)
320 {
321 //====== 横線
322
323 pat_end = (pat + max.x - min.x) & 3;
324
325 if(min.x <= rcclip->x2 && max.x >= rcclip->x1
326 && y1 >= rcclip->y1 && y1 <= rcclip->y2)
327 {
328 dir = (x1 < x2)? 1: -1;
329
330 x1 = min.x, x2 = max.x;
331 if(dir < 0) pat = pat_end;
332
333 if(x1 < rcclip->x1)
334 {
335 pat = (pat + (rcclip->x1 - x1) * dir) & 3;
336 x1 = rcclip->x1;
337 }
338
339 if(x2 > rcclip->x2) x2 = rcclip->x2;
340
341 pd = mPixbufGetBufPtFast(p, x1, y1);
342
343 for(dx = x2 - x1 + 1; dx; dx--, pd += p->bpp, pat = (pat + dir) & 3)
344 (p->setbuf)(pd, col[pat]);
345 }
346
347 return pat_end;
348 }
349 else if(x1 == x2)
350 {
351 //====== 縦線
352
353 pat_end = (pat + max.y - min.y) & 3;
354
355 if(x1 >= rcclip->x1 && x1 <= rcclip->x2
356 && min.y <= rcclip->y2 && max.y >= rcclip->y1)
357 {
358 dir = (y1 < y2)? 1: -1;
359
360 y1 = min.y, y2 = max.y;
361 if(dir < 0) pat = pat_end;
362
363 if(y1 < rcclip->y1)
364 {
365 pat = (pat + (rcclip->y1 - y1) * dir) & 3;
366 y1 = rcclip->y1;
367 }
368
369 if(y2 > rcclip->y2) y2 = rcclip->y2;
370
371 pd = mPixbufGetBufPtFast(p, x1, y1);
372
373 for(dy = y2 - y1 + 1; dy; dy--, pd += p->pitch_dir, pat = (pat + dir) & 3)
374 (p->setbuf)(pd, col[pat]);
375 }
376
377 return pat_end;
378 }
379 else
380 {
381 //====== 斜め
382
383 dx = max.x - min.x;
384 dy = max.y - min.y;
385
386 if(dx > dy)
387 pat_end = (pat + max.x - min.x) & 3;
388 else
389 pat_end = (pat + max.y - min.y) & 3;
390
391 //範囲外
392
393 if(min.x > rcclip->x2 || max.x < rcclip->x1
394 || min.y > rcclip->y2 || max.y < rcclip->y1)
395 return pat_end;
396
397 //
398
399 if(dx > dy)
400 {
401 //----- 横長
402
403 dir = (x1 < x2)? 1: -1;
404
405 //x1 -> x2 の方向にする
406
407 if(dir < 0)
408 {
409 x1 = min.x, x2 = max.x;
410 tmp = y1, y1 = y2, y2 = tmp;
411 pat = pat_end;
412 }
413
414 inc = ((int64_t)(y2 - y1) << 16) / dx;
415 f = (int64_t)y1 << 16;
416
417 //X クリッピング
418
419 if(x1 < rcclip->x1)
420 {
421 pat = (pat + (rcclip->x1 - x1) * dir) & 3;
422 f += inc * (rcclip->x1 - x1);
423 x1 = rcclip->x1;
424 }
425
426 if(x2 > rcclip->x2) x2 = rcclip->x2;
427
428 //
429
430 tmp = (f + (1<<15)) >> 16;
431
432 if(y1 < y2)
433 {
434 //----- Y が下方向
435
436 //開始位置が範囲外
437
438 if(tmp > rcclip->y2) return pat_end;
439
440 //範囲内まで進める
441
442 while(tmp < rcclip->y1)
443 {
444 x1++;
445 f += inc;
446 pat = (pat + dir) & 3;
447
448 tmp = (f + (1<<15)) >> 16;
449 }
450
451 //描画
452
453 for(; x1 <= x2; x1++, f += inc, pat = (pat + dir) & 3)
454 {
455 tmp = (f + (1<<15)) >> 16;
456 if(tmp > rcclip->y2) break;
457
458 mPixbufSetPixel(p, x1, tmp, col[pat]);
459 }
460 }
461 else
462 {
463 //----- Y が上方向
464
465 //開始位置が範囲外
466
467 if(tmp < rcclip->y1) return pat_end;
468
469 //範囲内まで進める
470
471 while(tmp > rcclip->y2)
472 {
473 x1++;
474 f += inc;
475 pat = (pat + dir) & 3;
476
477 tmp = (f + (1<<15)) >> 16;
478 }
479
480 //描画
481
482 for(; x1 <= x2; x1++, f += inc, pat = (pat + dir) & 3)
483 {
484 tmp = (f + (1<<15)) >> 16;
485 if(tmp < rcclip->y1) break;
486
487 mPixbufSetPixel(p, x1, tmp, col[pat]);
488 }
489 }
490 }
491 else
492 {
493 //------ 縦長
494
495 dir = (y1 < y2)? 1: -1;
496
497 //y1 -> y2 の方向にする
498
499 if(y1 > y2)
500 {
501 y1 = min.y, y2 = max.y;
502 tmp = x1, x1 = x2, x2 = tmp;
503 pat = pat_end;
504 }
505
506 inc = ((int64_t)(x2 - x1) << 16) / dy;
507 f = (int64_t)x1 << 16;
508
509 //Y クリッピング
510
511 if(y1 < rcclip->y1)
512 {
513 pat = (pat + (rcclip->y1 - y1) * dir) & 3;
514 f += inc * (rcclip->y1 - y1);
515 y1 = rcclip->y1;
516 }
517
518 if(y2 > rcclip->y2) y2 = rcclip->y2;
519
520 //
521
522 tmp = (f + (1<<15)) >> 16;
523
524 if(x1 < x2)
525 {
526 //----- X が右方向
527
528 //開始位置が範囲外
529
530 if(tmp > rcclip->x2) return pat_end;
531
532 //範囲内まで進める
533
534 while(tmp < rcclip->x1)
535 {
536 y1++;
537 f += inc;
538 pat = (pat + dir) & 3;
539
540 tmp = (f + (1<<15)) >> 16;
541 }
542
543 //描画
544
545 for(; y1 <= y2; y1++, f += inc, pat = (pat + dir) & 3)
546 {
547 tmp = (f + (1<<15)) >> 16;
548 if(tmp > rcclip->x2) break;
549
550 mPixbufSetPixel(p, tmp, y1, col[pat]);
551 }
552 }
553 else
554 {
555 //----- X が左方向
556
557 //開始位置が範囲外
558
559 if(tmp < rcclip->x1) return pat_end;
560
561 //範囲内まで進める
562
563 while(tmp > rcclip->x2)
564 {
565 y1++;
566 f += inc;
567 pat = (pat + dir) & 3;
568
569 tmp = (f + (1<<15)) >> 16;
570 }
571
572 //描画
573
574 for(; y1 <= y2; y1++, f += inc, pat = (pat + dir) & 3)
575 {
576 tmp = (f + (1<<15)) >> 16;
577 if(tmp < rcclip->x1) break;
578
579 mPixbufSetPixel(p, tmp, y1, col[pat]);
580 }
581 }
582 }
583
584 return pat_end;
585 }
586 }
587
588
589 //===========================
590 //
591 //===========================
592
593
594 /** 白黒破線の十字線描画
595 *
596 * キャンバスビューのルーペ時。
597 *
598 * @param x 左側の垂直線の位置
599 * @param y 上側の水平線の位置
600 * @param size 2つの線の間隔
601 * @param box 描画範囲 */
602
pixbufDraw_cross_dash(mPixbuf * pixbuf,int x,int y,int size,mBox * boxarea)603 void pixbufDraw_cross_dash(mPixbuf *pixbuf,int x,int y,int size,mBox *boxarea)
604 {
605 mPixCol col[2];
606 mBox box;
607 uint8_t *pd;
608 int i,n;
609
610 if(!mPixbufGetClipBox_box(pixbuf, &box, boxarea))
611 return;
612
613 col[0] = 0;
614 col[1] = MSYSCOL(WHITE);
615
616 //水平線、上 (実際には y - 1 の位置)
617
618 n = y - 1;
619
620 if(box.y <= n && n < box.y + box.h)
621 {
622 pd = mPixbufGetBufPtFast(pixbuf, box.x, n);
623 n = box.x;
624
625 for(i = box.w; i; i--, pd += pixbuf->bpp, n++)
626 {
627 if(n < x || n >= x + size)
628 (pixbuf->setbuf)(pd, col[(n >> 1) & 1]);
629 }
630 }
631
632 //水平線、下
633
634 n = y + size;
635
636 if(box.y <= n && n < box.y + box.h)
637 {
638 pd = mPixbufGetBufPtFast(pixbuf, box.x, n);
639 n = box.x;
640
641 for(i = box.w; i; i--, pd += pixbuf->bpp, n++)
642 {
643 if(n < x || n >= x + size)
644 (pixbuf->setbuf)(pd, col[(n >> 1) & 1]);
645 }
646 }
647
648 //垂直線、左
649
650 n = x - 1;
651
652 if(box.x <= n && n < box.x + box.w)
653 {
654 pd = mPixbufGetBufPtFast(pixbuf, n, box.y);
655 n = box.y;
656
657 for(i = box.h; i; i--, pd += pixbuf->pitch_dir, n++)
658 {
659 if(n < y || n >= y + size)
660 (pixbuf->setbuf)(pd, col[(n >> 1) & 1]);
661 }
662 }
663
664 //垂直線、右
665
666 n = x + size;
667
668 if(box.x <= n && n < box.x + box.w)
669 {
670 pd = mPixbufGetBufPtFast(pixbuf, n, box.y);
671 n = box.y;
672
673 for(i = box.h; i; i--, pd += pixbuf->pitch_dir, n++)
674 {
675 if(n < y || n >= y + size)
676 (pixbuf->setbuf)(pd, col[(n >> 1) & 1]);
677 }
678 }
679 }
680
681 /** 白黒破線の矩形枠描画 (フィルタプレビュー用) */
682
pixbufDraw_dashBox_mono(mPixbuf * pixbuf,int x,int y,int w,int h)683 void pixbufDraw_dashBox_mono(mPixbuf *pixbuf,int x,int y,int w,int h)
684 {
685 mPixCol col[2];
686 int i,n,pos = 0;
687
688 col[0] = 0;
689 col[1] = MSYSCOL(WHITE);
690
691 //上
692
693 for(i = 0; i < w; i++, pos++)
694 mPixbufSetPixel(pixbuf, x + i, y, col[(pos >> 1) & 1]);
695
696 //右
697
698 n = x + w - 1;
699
700 for(i = 1; i < h; i++, pos++)
701 mPixbufSetPixel(pixbuf, n, y + i, col[(pos >> 1) & 1]);
702
703 //下
704
705 n = y + h - 1;
706
707 for(i = w - 2; i >= 0; i--, pos++)
708 mPixbufSetPixel(pixbuf, x + i, n, col[(pos >> 1) & 1]);
709
710 //左
711
712 for(i = h - 2; i > 0; i--, pos++)
713 mPixbufSetPixel(pixbuf, x, y + i, col[(pos >> 1) & 1]);
714 }
715
716 /** 選択範囲の枠を描画 */
717
pixbufDrawSelectBox(mPixbuf * pixbuf,mBox * boximg,CanvasDrawInfo * info)718 void pixbufDrawSelectBox(mPixbuf *pixbuf,mBox *boximg,CanvasDrawInfo *info)
719 {
720 mRect rcclip;
721 mPoint pt[4];
722 double x1,y1,x2,y2;
723 int pat;
724
725 //描画先のクリッピング範囲 (rect)
726
727 mRectSetByBox(&rcclip, &info->boxdst);
728
729 //
730
731 x1 = boximg->x, y1 = boximg->y;
732 x2 = boximg->x + boximg->w, y2 = boximg->y + boximg->h;
733
734 if(info->param->rd == 0)
735 {
736 //----- 回転なし
737
738 CanvasDrawInfo_imageToarea_pt(info, x1, y1, pt);
739 CanvasDrawInfo_imageToarea_pt(info, x2, y2, pt + 1);
740
741 //左上を -1px
742
743 pt[0].y--;
744
745 if(info->mirror)
746 pt[0].x++;
747 else
748 pt[0].x--;
749
750 //描画
751
752 pat = _drawline_dash_clip(pixbuf, pt[0].x, pt[0].y, pt[1].x, pt[0].y, 0, &rcclip);
753 pat = _drawline_dash_clip(pixbuf, pt[1].x, pt[0].y, pt[1].x, pt[1].y, pat, &rcclip);
754 pat = _drawline_dash_clip(pixbuf, pt[1].x, pt[1].y, pt[0].x, pt[1].y, pat, &rcclip);
755 _drawline_dash_clip(pixbuf, pt[0].x, pt[1].y, pt[0].x, pt[0].y, pat, &rcclip);
756 }
757 else
758 {
759 //----- 回転あり
760
761 //左上を -1px するため、イメージ座標で 1px に相当する値を引く
762
763 x1 -= info->param->scalediv;
764 y1 -= info->param->scalediv;
765
766 CanvasDrawInfo_imageToarea_pt(info, x1, y1, pt);
767 CanvasDrawInfo_imageToarea_pt(info, x2, y1, pt + 1);
768 CanvasDrawInfo_imageToarea_pt(info, x2, y2, pt + 2);
769 CanvasDrawInfo_imageToarea_pt(info, x1, y2, pt + 3);
770
771 //描画
772
773 pat = _drawline_dash_clip(pixbuf, pt[0].x, pt[0].y, pt[1].x, pt[1].y, 0, &rcclip);
774 pat = _drawline_dash_clip(pixbuf, pt[1].x, pt[1].y, pt[2].x, pt[2].y, pat, &rcclip);
775 pat = _drawline_dash_clip(pixbuf, pt[2].x, pt[2].y, pt[3].x, pt[3].y, pat, &rcclip);
776 _drawline_dash_clip(pixbuf, pt[3].x, pt[3].y, pt[0].x, pt[0].y, pat, &rcclip);
777 }
778 }
779
780 /** キャンバスにグリッド線描画
781 *
782 * @param boxdst 描画先の範囲
783 * @param boximg boxdst の範囲に相当するイメージ座標での範囲
784 * @param rcgrid グリッドを描画するイメージ範囲 (NULL で全体) */
785
pixbufDrawGrid(mPixbuf * pixbuf,mBox * boxdst,mBox * boximg,int gridw,int gridh,uint32_t col,mRect * rcgrid,CanvasDrawInfo * info)786 void pixbufDrawGrid(mPixbuf *pixbuf,mBox *boxdst,mBox *boximg,
787 int gridw,int gridh,uint32_t col,mRect *rcgrid,CanvasDrawInfo *info)
788 {
789 mRect rcclip;
790 int top,bottom,i;
791 double inc[4],x1,y1,x2,y2,incx,incy;
792 mBool inarea;
793
794 //描画先のクリッピング範囲 (rect)
795
796 mRectSetByBox(&rcclip, boxdst);
797
798 //イメージ座標 +1 時のキャンバス座標変化値
799
800 CanvasDrawInfo_getImageIncParam(info, inc);
801
802 //--------- 縦線
803
804 top = boximg->x;
805 bottom = boximg->x + boximg->w - 1;
806 inarea = TRUE;
807
808 if(rcgrid)
809 {
810 //グリッド範囲あり
811
812 if(top > rcgrid->x2 || bottom < rcgrid->x1)
813 inarea = FALSE;
814 else
815 {
816 if(top < rcgrid->x1) top = rcgrid->x1;
817 if(bottom > rcgrid->x2) bottom = rcgrid->x2;
818
819 top = (top - rcgrid->x1) / gridw * gridw + rcgrid->x1;
820 bottom = (bottom - rcgrid->x1) / gridw * gridw + rcgrid->x1;
821
822 CanvasDrawInfo_imageToarea(info, top, rcgrid->y1, &x1, &y1);
823 CanvasDrawInfo_imageToarea(info, top, rcgrid->y2, &x2, &y2);
824 }
825 }
826 else
827 {
828 //全体
829
830 top = top / gridw * gridw;
831 bottom = bottom / gridw * gridw;
832
833 CanvasDrawInfo_imageToarea(info, top, 0, &x1, &y1);
834 CanvasDrawInfo_imageToarea(info, top, info->imgh, &x2, &y2);
835 }
836
837 //描画
838
839 if(inarea)
840 {
841 incx = inc[0] * gridw;
842 incy = inc[1] * gridw;
843
844 for(i = top; i <= bottom; i += gridw)
845 {
846 _drawline_blend_clip(pixbuf, x1, y1, x2, y2, col, &rcclip);
847
848 x1 += incx, y1 += incy;
849 x2 += incx, y2 += incy;
850 }
851 }
852
853 //--------- 横線
854
855 top = boximg->y;
856 bottom = boximg->y + boximg->h - 1;
857 inarea = TRUE;
858
859 if(rcgrid)
860 {
861 //グリッド範囲あり
862
863 if(top > rcgrid->y2 || bottom < rcgrid->y1)
864 inarea = FALSE;
865 else
866 {
867 if(top < rcgrid->y1) top = rcgrid->y1;
868 if(bottom > rcgrid->y2) bottom = rcgrid->y2;
869
870 top = (top - rcgrid->y1) / gridh * gridh + rcgrid->y1;
871 bottom = (bottom - rcgrid->y1) / gridh * gridh + rcgrid->y1;
872
873 CanvasDrawInfo_imageToarea(info, rcgrid->x1, top, &x1, &y1);
874 CanvasDrawInfo_imageToarea(info, rcgrid->x2, top, &x2, &y2);
875 }
876 }
877 else
878 {
879 //全体
880
881 top = top / gridh * gridh;
882 bottom = bottom / gridh * gridh;
883
884 CanvasDrawInfo_imageToarea(info, 0, top, &x1, &y1);
885 CanvasDrawInfo_imageToarea(info, info->imgw, top, &x2, &y2);
886 }
887
888 //描画
889
890 if(inarea)
891 {
892 incx = inc[2] * gridh;
893 incy = inc[3] * gridh;
894
895 for(i = top; i <= bottom; i += gridh)
896 {
897 _drawline_blend_clip(pixbuf, x1, y1, x2, y2, col, &rcclip);
898
899 x1 += incx, y1 += incy;
900 x2 += incx, y2 += incy;
901 }
902 }
903 }
904