aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32term.c
diff options
context:
space:
mode:
authorAlp Aker2012-06-16 20:32:36 -0400
committerAlp Aker2012-06-16 20:32:36 -0400
commit9b0e3ebaef5aed8097965b14c97a0579763be7fd (patch)
treeeeabc5495c58289454d9c53c9dd409377ec72cf3 /src/w32term.c
parent40d8bcb854203237c6ad8327bc1fc0644f8734ec (diff)
downloademacs-9b0e3ebaef5aed8097965b14c97a0579763be7fd.tar.gz
emacs-9b0e3ebaef5aed8097965b14c97a0579763be7fd.zip
Implement wave-style variant of underlining.
* doc/lispref/display.texi: Document new face attribute. * lisp/cus-face.el (custom-face-attributes): Add wave-style underline attribute. * lisp/faces.el (set-face-attribute): Update docstring. * src/dispextern.h (face_underline_type): New enum. (face): Add field for underline type. * src/nsterm.m (ns_draw_underwave): New function. (ns_draw_text_decoration): Use it. * src/w32term.c (w32_restore_glyph_string_clip, w32_draw_underwave): New functions. (x_draw_glyph_string): Use them. * src/xfaces.c (Qline, Qwave): New Lisp objects. (check_lface_attrs, merge_face_ref) (Finternal_set_lisp_face_attribute, realize_x_face): Handle wave-style underline face attributes. * src/xterm.c (x_draw_underwave): New function. (x_draw_glyph_string): Use it.
Diffstat (limited to 'src/w32term.c')
-rw-r--r--src/w32term.c196
1 files changed, 149 insertions, 47 deletions
diff --git a/src/w32term.c b/src/w32term.c
index 38120b77ac9..6a4b3ca4afb 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -313,6 +313,94 @@ w32_set_clip_rectangle (HDC hdc, RECT *rect)
313 SelectClipRgn (hdc, NULL); 313 SelectClipRgn (hdc, NULL);
314} 314}
315 315
316/* Restore clipping rectangle in S */
317static void
318w32_restore_glyph_string_clip (struct glyph_string *s)
319{
320 RECT *r = s->clip;
321 int n = s->num_clips;
322
323 if (n == 1)
324 w32_set_clip_rectangle (s->hdc, r);
325 else if (n > 1)
326 {
327 HRGN clip1 = CreateRectRgnIndirect (r);
328 HRGN clip2 = CreateRectRgnIndirect (r + 1);
329 if (CombineRgn (clip1, clip1, clip2, RGN_OR) != ERROR)
330 SelectClipRgn (s->hdc, clip1);
331 DeleteObject (clip1);
332 DeleteObject (clip2);
333 }
334}
335
336/*
337 Draw a wavy line under S. The wave fills wave_height pixels from y0.
338
339 x0 wave_length = 2
340 --
341 y0 * * * * *
342 |* * * * * * * * *
343 wave_height = 3 | * * * *
344
345*/
346
347void
348w32_draw_underwave (struct glyph_string *s, COLORREF color)
349{
350 int wave_height = 2, wave_length = 3;
351 int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
352 XRectangle wave_clip, string_clip, final_clip;
353 RECT w32_final_clip, w32_string_clip;
354 HPEN hp, oldhp;
355
356 dx = wave_length;
357 dy = wave_height - 1;
358 x0 = s->x;
359 y0 = s->ybase + 1;
360 width = s->width;
361 xmax = x0 + width;
362
363 /* Find and set clipping rectangle */
364
365 wave_clip = (XRectangle){ x0, y0, width, wave_height };
366 get_glyph_string_clip_rect (s, &w32_string_clip);
367 CONVERT_TO_XRECT (string_clip, w32_string_clip);
368
369 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
370 return;
371
372 hp = CreatePen (PS_SOLID, 0, color);
373 oldhp = SelectObject (s->hdc, hp);
374 CONVERT_FROM_XRECT (final_clip, w32_final_clip);
375 w32_set_clip_rectangle (s->hdc, &w32_final_clip);
376
377 /* Draw the waves */
378
379 x1 = x0 - (x0 % dx);
380 x2 = x1 + dx;
381 odd = (x1/dx) % 2;
382 y1 = y2 = y0;
383
384 if (odd)
385 y1 += dy;
386 else
387 y2 += dy;
388
389 MoveToEx (s->hdc, x1, y1, NULL);
390
391 while (x1 <= xmax)
392 {
393 LineTo (s->hdc, x2, y2);
394 x1 = x2, y1 = y2;
395 x2 += dx, y2 = y0 + odd*dy;
396 odd = !odd;
397 }
398
399 /* Restore previous pen and clipping rectangle(s) */
400 w32_restore_glyph_string_clip (s);
401 SelectObject (s->hdc, oldhp);
402 DeleteObject (hp);
403}
316 404
317/* Draw a hollow rectangle at the specified position. */ 405/* Draw a hollow rectangle at the specified position. */
318void 406void
@@ -2347,60 +2435,74 @@ x_draw_glyph_string (struct glyph_string *s)
2347 /* Draw underline. */ 2435 /* Draw underline. */
2348 if (s->face->underline_p) 2436 if (s->face->underline_p)
2349 { 2437 {
2350 unsigned long thickness, position; 2438 if (s->face->underline_type == FACE_UNDER_WAVE)
2351 int y;
2352
2353 if (s->prev && s->prev->face->underline_p)
2354 { 2439 {
2355 /* We use the same underline style as the previous one. */ 2440 COLORREF color;
2356 thickness = s->prev->underline_thickness; 2441
2357 position = s->prev->underline_position; 2442 if (s->face->underline_defaulted_p)
2443 color = s->gc->foreground;
2444 else
2445 color = s->face->underline_color;
2446
2447 w32_draw_underwave (s, color);
2358 } 2448 }
2359 else 2449 else if (s->face->underline_type == FACE_UNDER_LINE)
2360 { 2450 {
2361 /* Get the underline thickness. Default is 1 pixel. */ 2451 unsigned long thickness, position;
2362 if (s->font && s->font->underline_thickness > 0) 2452 int y;
2363 thickness = s->font->underline_thickness; 2453
2454 if (s->prev && s->prev->face->underline_p)
2455 {
2456 /* We use the same underline style as the previous one. */
2457 thickness = s->prev->underline_thickness;
2458 position = s->prev->underline_position;
2459 }
2364 else 2460 else
2365 thickness = 1; 2461 {
2366 if (x_underline_at_descent_line) 2462 /* Get the underline thickness. Default is 1 pixel. */
2367 position = (s->height - thickness) - (s->ybase - s->y); 2463 if (s->font && s->font->underline_thickness > 0)
2464 thickness = s->font->underline_thickness;
2465 else
2466 thickness = 1;
2467 if (x_underline_at_descent_line)
2468 position = (s->height - thickness) - (s->ybase - s->y);
2469 else
2470 {
2471 /* Get the underline position. This is the recommended
2472 vertical offset in pixels from the baseline to the top of
2473 the underline. This is a signed value according to the
2474 specs, and its default is
2475
2476 ROUND ((maximum_descent) / 2), with
2477 ROUND (x) = floor (x + 0.5) */
2478
2479 if (x_use_underline_position_properties
2480 && s->font && s->font->underline_position >= 0)
2481 position = s->font->underline_position;
2482 else if (s->font)
2483 position = (s->font->descent + 1) / 2;
2484 }
2485 position = max (position, underline_minimum_offset);
2486 }
2487 /* Check the sanity of thickness and position. We should
2488 avoid drawing underline out of the current line area. */
2489 if (s->y + s->height <= s->ybase + position)
2490 position = (s->height - 1) - (s->ybase - s->y);
2491 if (s->y + s->height < s->ybase + position + thickness)
2492 thickness = (s->y + s->height) - (s->ybase + position);
2493 s->underline_thickness = thickness;
2494 s->underline_position =position;
2495 y = s->ybase + position;
2496 if (s->face->underline_defaulted_p)
2497 {
2498 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2499 y, s->width, 1);
2500 }
2368 else 2501 else
2369 { 2502 {
2370 /* Get the underline position. This is the recommended 2503 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
2371 vertical offset in pixels from the baseline to the top of 2504 y, s->width, 1);
2372 the underline. This is a signed value according to the
2373 specs, and its default is
2374
2375 ROUND ((maximum_descent) / 2), with
2376 ROUND (x) = floor (x + 0.5) */
2377
2378 if (x_use_underline_position_properties
2379 && s->font && s->font->underline_position >= 0)
2380 position = s->font->underline_position;
2381 else if (s->font)
2382 position = (s->font->descent + 1) / 2;
2383 } 2505 }
2384 position = max (position, underline_minimum_offset);
2385 }
2386 /* Check the sanity of thickness and position. We should
2387 avoid drawing underline out of the current line area. */
2388 if (s->y + s->height <= s->ybase + position)
2389 position = (s->height - 1) - (s->ybase - s->y);
2390 if (s->y + s->height < s->ybase + position + thickness)
2391 thickness = (s->y + s->height) - (s->ybase + position);
2392 s->underline_thickness = thickness;
2393 s->underline_position =position;
2394 y = s->ybase + position;
2395 if (s->face->underline_defaulted_p)
2396 {
2397 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2398 y, s->width, 1);
2399 }
2400 else
2401 {
2402 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
2403 y, s->width, 1);
2404 } 2506 }
2405 } 2507 }
2406 /* Draw overline. */ 2508 /* Draw overline. */