(linenum→info "unix/slp.c:2238")

emacs/22.1/src/fringe.c

    1: /* Fringe handling (split from xdisp.c).
    2:    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997,
    3:                  1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    4:                  2006, 2007  Free Software Foundation, Inc.
    5: 
    6: This file is part of GNU Emacs.
    7: 
    8: GNU Emacs is free software; you can redistribute it and/or modify
    9: it under the terms of the GNU General Public License as published by
   10: the Free Software Foundation; either version 2, or (at your option)
   11: any later version.
   12: 
   13: GNU Emacs is distributed in the hope that it will be useful,
   14: but WITHOUT ANY WARRANTY; without even the implied warranty of
   15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16: GNU General Public License for more details.
   17: 
   18: You should have received a copy of the GNU General Public License
   19: along with GNU Emacs; see the file COPYING.  If not, write to
   20: the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   21: Boston, MA 02110-1301, USA.  */
   22: 
   23: #include <config.h>
   24: #include <stdio.h>
   25: 
   26: #include "lisp.h"
   27: #include "frame.h"
   28: #include "window.h"
   29: #include "dispextern.h"
   30: #include "buffer.h"
   31: #include "blockinput.h"
   32: 
   33: #ifdef HAVE_WINDOW_SYSTEM
   34: 
   35: extern Lisp_Object Qfringe;
   36: extern Lisp_Object Qtop, Qbottom, Qcenter;
   37: extern Lisp_Object Qup, Qdown, Qleft, Qright;
   38: 
   39: /* Non-nil means that newline may flow into the right fringe.  */
   40: 
   41: Lisp_Object Voverflow_newline_into_fringe;
   42: 
   43: /* List of known fringe bitmap symbols.
   44: 
   45:    The fringe bitmap number is stored in the `fringe' property on
   46:    those symbols.  Names for the built-in bitmaps are installed by
   47:    loading fringe.el.
   48:  */
   49: 
   50: Lisp_Object Vfringe_bitmaps;
   51: 
   52: /* Fringe bitmaps are represented in three different ways:
   53: 
   54:    Logical bitmaps are used internally to denote things like
   55:    'end-of-buffer', 'left-truncation', 'overlay-arrow', etc.
   56: 
   57:    Physical bitmaps specify the visual appearence of the bitmap,
   58:    e.g. 'bottom-left-angle', 'left-arrow', 'left-triangle', etc.
   59:    User defined bitmaps are physical bitmaps.
   60: 
   61:    Internally, fringe bitmaps for a specific display row are
   62:    represented as a simple integer that is used as an index
   63:    into the table of all defined bitmaps.  This index is stored
   64:    in the `fringe' property of the physical bitmap symbol.
   65: 
   66:    Logical bitmaps are mapped to physical bitmaps through the
   67:    buffer-local `fringe-indicator-alist' variable.
   68: 
   69:    Each element of this alist is a cons (LOGICAL . PHYSICAL)
   70:    mapping a logical bitmap to a physical bitmap.
   71:    PHYSICAL is either a symbol to use in both left and right fringe,
   72:    or a cons of two symbols (LEFT . RIGHT) denoting different
   73:    bitmaps to use in left and right fringe.
   74: 
   75:    LOGICAL is first looked up in the window's buffer's buffer-local
   76:    value of the fringe-indicator-alist variable, and if not present,
   77:    in the global value of fringe-indicator-alist.
   78: 
   79:    If LOGICAL is not present in either alist, or the PHYSICAL value
   80:    found is nil, no bitmap is shown for the logical bitmap.
   81: 
   82:    The `left-fringe' and `right-fringe' display properties
   83:    must specify physical bitmap symbols.
   84: */
   85: 
   86: extern Lisp_Object Qunknown;
   87: Lisp_Object Qtruncation, Qcontinuation, Qoverlay_arrow;
   88: Lisp_Object Qempty_line, Qtop_bottom;
   89: extern Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
   90: Lisp_Object Qhollow_small;
   91: 
   92: enum fringe_bitmap_align
   93: {
   94:   ALIGN_BITMAP_CENTER = 0,
   95:   ALIGN_BITMAP_TOP,
   96:   ALIGN_BITMAP_BOTTOM
   97: };
   98: 
   99: struct fringe_bitmap
  100: {
  101:   unsigned short *bits;
  102:   unsigned height : 8;
  103:   unsigned width : 8;
  104:   unsigned period : 8;
  105:   unsigned align : 2;
  106:   unsigned dynamic : 1;
  107: };
  108: 
  109: ^L
  110: /***********************************************************************
  111:                                Fringe bitmaps
  112:  ***********************************************************************/
  113: 
  114: /* Undefined bitmap.  A question mark.  */
  115: /*
  116:   ..xxxx..
  117:   .xxxxxx.
  118:   xx....xx
  119:   xx....xx
  120:   ....xx..
  121:   ...xx...
  122:   ...xx...
  123:   ........
  124:   ...xx...
  125:   ...xx...
  126: */
  127: static unsigned short question_mark_bits[] = {
  128:   0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
  129: 
  130: /* An arrow like this: `<-'.  */
  131: /*
  132:   ...xx...
  133:   ..xx....
  134:   .xx.....
  135:   xxxxxx..
  136:   xxxxxx..
  137:   .xx.....
  138:   ..xx....
  139:   ...xx...
  140: */
  141: static unsigned short left_arrow_bits[] = {
  142:    0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
  143: 
  144: 
  145: /* Right truncation arrow bitmap `->'.  */
  146: /*
  147:   ...xx...
  148:   ....xx..
  149:   .....xx.
  150:   ..xxxxxx
  151:   ..xxxxxx
  152:   .....xx.
  153:   ....xx..
  154:   ...xx...
  155: */
  156: static unsigned short right_arrow_bits[] = {
  157:    0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
  158: 
  159: 
  160: /* Up arrow bitmap.  */
  161: /*
  162:   ...xx...
  163:   ..xxxx..
  164:   .xxxxxx.
  165:   xxxxxxxx
  166:   ...xx...
  167:   ...xx...
  168:   ...xx...
  169:   ...xx...
  170: */
  171: static unsigned short up_arrow_bits[] = {
  172:    0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
  173: 
  174: 
  175: /* Down arrow bitmap.  */
  176: /*
  177:   ...xx...
  178:   ...xx...
  179:   ...xx...
  180:   ...xx...
  181:   xxxxxxxx
  182:   .xxxxxx.
  183:   ..xxxx..
  184:   ...xx...
  185: */
  186: static unsigned short down_arrow_bits[] = {
  187:    0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
  188: 
  189: /* Marker for continuation lines.  */
  190: /*
  191:   ..xxxx..
  192:   .xxxxx..
  193:   xx......
  194:   xxx..x..
  195:   xxxxxx..
  196:   .xxxxx..
  197:   ..xxxx..
  198:   .xxxxx..
  199: */
  200: static unsigned short left_curly_arrow_bits[] = {
  201:    0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
  202: 
  203: /* Marker for continued lines.  */
  204: /*
  205:   ..xxxx..
  206:   ..xxxxx.
  207:   ......xx
  208:   ..x..xxx
  209:   ..xxxxxx
  210:   ..xxxxx.
  211:   ..xxxx..
  212:   ..xxxxx.
  213: */
  214: static unsigned short right_curly_arrow_bits[] = {
  215:    0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
  216: 
  217: /* Reverse Overlay arrow bitmap.  A triangular arrow.  */
  218: /*
  219:   ......xx
  220:   ....xxxx
  221:   ...xxxxx
  222:   ..xxxxxx
  223:   ..xxxxxx
  224:   ...xxxxx
  225:   ....xxxx
  226:   ......xx
  227: */
  228: static unsigned short left_triangle_bits[] = {
  229:    0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
  230: 
  231: /* Overlay arrow bitmap.  A triangular arrow.  */
  232: /*
  233:   xx......
  234:   xxxx....
  235:   xxxxx...
  236:   xxxxxx..
  237:   xxxxxx..
  238:   xxxxx...
  239:   xxxx....
  240:   xx......
  241: */
  242: static unsigned short right_triangle_bits[] = {
  243:    0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
  244: 
  245: /* First line bitmap.  An top-left angle.  */
  246: /*
  247:   xxxxxx..
  248:   xxxxxx..
  249:   xx......
  250:   xx......
  251:   xx......
  252:   xx......
  253:   xx......
  254:   ........
  255: */
  256: static unsigned short top_left_angle_bits[] = {
  257:    0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
  258: 
  259: /* First line bitmap.  An right-up angle.  */
  260: /*
  261:   ..xxxxxx
  262:   ..xxxxxx
  263:   ......xx
  264:   ......xx
  265:   ......xx
  266:   ......xx
  267:   ......xx
  268:   ........
  269: */
  270: static unsigned short top_right_angle_bits[] = {
  271:    0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
  272: 
  273: /* Last line bitmap.  An left-down angle.  */
  274: /*
  275:   ........
  276:   xx......
  277:   xx......
  278:   xx......
  279:   xx......
  280:   xx......
  281:   xxxxxx..
  282:   xxxxxx..
  283: */
  284: static unsigned short bottom_left_angle_bits[] = {
  285:    0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
  286: 
  287: /* Last line bitmap.  An right-down angle.  */
  288: /*
  289:   ........
  290:   ......xx
  291:   ......xx
  292:   ......xx
  293:   ......xx
  294:   ......xx
  295:   ..xxxxxx
  296:   ..xxxxxx
  297: */
  298: static unsigned short bottom_right_angle_bits[] = {
  299:    0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
  300: 
  301: /* First/last line bitmap.  An left bracket.  */
  302: /*
  303:   xxxxxx..
  304:   xxxxxx..
  305:   xx......
  306:   xx......
  307:   xx......
  308:   xx......
  309:   xx......
  310:   xx......
  311:   xxxxxx..
  312:   xxxxxx..
  313: */
  314: static unsigned short left_bracket_bits[] = {
  315:    0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
  316: 
  317: /* First/last line bitmap.  An right bracket.  */
  318: /*
  319:   ..xxxxxx
  320:   ..xxxxxx
  321:   ......xx
  322:   ......xx
  323:   ......xx
  324:   ......xx
  325:   ......xx
  326:   ......xx
  327:   ..xxxxxx
  328:   ..xxxxxx
  329: */
  330: static unsigned short right_bracket_bits[] = {
  331:   0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
  332: 
  333: /* Filled box cursor bitmap.  A filled box; max 13 pixels high.  */
  334: /*
  335:   xxxxxxx.
  336:   xxxxxxx.
  337:   xxxxxxx.
  338:   xxxxxxx.
  339:   xxxxxxx.
  340:   xxxxxxx.
  341:   xxxxxxx.
  342:   xxxxxxx.
  343:   xxxxxxx.
  344:   xxxxxxx.
  345:   xxxxxxx.
  346:   xxxxxxx.
  347:   xxxxxxx.
  348: */
  349: static unsigned short filled_rectangle_bits[] = {
  350:    0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  351: 
  352: /* Hollow box cursor bitmap.  A hollow box; max 13 pixels high.  */
  353: /*
  354:   xxxxxxx.
  355:   x.....x.
  356:   x.....x.
  357:   x.....x.
  358:   x.....x.
  359:   x.....x.
  360:   x.....x.
  361:   x.....x.
  362:   x.....x.
  363:   x.....x.
  364:   x.....x.
  365:   x.....x.
  366:   xxxxxxx.
  367: */
  368: static unsigned short hollow_rectangle_bits[] = {
  369:    0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
  370: 
  371: /* Hollow square bitmap.  */
  372: /*
  373:   .xxxxxx.
  374:   .x....x.
  375:   .x....x.
  376:   .x....x.
  377:   .x....x.
  378:   .xxxxxx.
  379: */
  380: static unsigned short hollow_square_bits[] = {
  381:    0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
  382: 
  383: /* Filled square bitmap.  */
  384: /*
  385:   .xxxxxx.
  386:   .xxxxxx.
  387:   .xxxxxx.
  388:   .xxxxxx.
  389:   .xxxxxx.
  390:   .xxxxxx.
  391: */
  392: static unsigned short filled_square_bits[] = {
  393:    0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e};
  394: 
  395: /* Bar cursor bitmap.  A vertical bar; max 13 pixels high.  */
  396: /*
  397:   xx......
  398:   xx......
  399:   xx......
  400:   xx......
  401:   xx......
  402:   xx......
  403:   xx......
  404:   xx......
  405:   xx......
  406:   xx......
  407:   xx......
  408:   xx......
  409:   xx......
  410: */
  411: static unsigned short vertical_bar_bits[] = {
  412:    0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
  413: 
  414: /* HBar cursor bitmap.  A horizontal bar; 2 pixels high.  */
  415: /*
  416:   xxxxxxx.
  417:   xxxxxxx.
  418: */
  419: static unsigned short horizontal_bar_bits[] = {
  420:   0xfe, 0xfe};
  421: 
  422: 
  423: /* Bitmap drawn to indicate lines not displaying text if
  424:    `indicate-empty-lines' is non-nil.  */
  425: /*
  426:   ........
  427:   ..xxxx..
  428:   ........
  429:   ........
  430:   ..xxxx..
  431:   ........
  432: */
  433: static unsigned short empty_line_bits[] = {
  434:   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
  435:   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
  436:   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
  437:   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
  438:   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
  439:   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
  440:   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
  441:   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
  442: 
  443: 
  444: #define BYTES_PER_BITMAP_ROW  (sizeof (unsigned short))
  445: #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
  446: #define FRBITS(bits)  bits, STANDARD_BITMAP_HEIGHT (bits)
  447: 
  448: /* NOTE:  The order of these bitmaps must match the sequence
  449:    used in fringe.el to define the corresponding symbols.  */
  450: 
  451: struct fringe_bitmap standard_bitmaps[] =
  452: {
  453:   { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
  454:   { FRBITS (question_mark_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
  455:   { FRBITS (left_arrow_bits),         8, 0, ALIGN_BITMAP_CENTER, 0 },
  456:   { FRBITS (right_arrow_bits),        8, 0, ALIGN_BITMAP_CENTER, 0 },
  457:   { FRBITS (up_arrow_bits),           8, 0, ALIGN_BITMAP_TOP,    0 },
  458:   { FRBITS (down_arrow_bits),         8, 0, ALIGN_BITMAP_BOTTOM, 0 },
  459:   { FRBITS (left_curly_arrow_bits),   8, 0, ALIGN_BITMAP_CENTER, 0 },
  460:   { FRBITS (right_curly_arrow_bits),  8, 0, ALIGN_BITMAP_CENTER, 0 },
  461:   { FRBITS (left_triangle_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
  462:   { FRBITS (right_triangle_bits),     8, 0, ALIGN_BITMAP_CENTER, 0 },
  463:   { FRBITS (top_left_angle_bits),     8, 0, ALIGN_BITMAP_TOP,    0 },
  464:   { FRBITS (top_right_angle_bits),    8, 0, ALIGN_BITMAP_TOP,    0 },
  465:   { FRBITS (bottom_left_angle_bits),  8, 0, ALIGN_BITMAP_BOTTOM, 0 },
  466:   { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
  467:   { FRBITS (left_bracket_bits),       8, 0, ALIGN_BITMAP_CENTER, 0 },
  468:   { FRBITS (right_bracket_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
  469:   { FRBITS (filled_rectangle_bits),   8, 0, ALIGN_BITMAP_CENTER, 0 },
  470:   { FRBITS (hollow_rectangle_bits),   8, 0, ALIGN_BITMAP_CENTER, 0 },
  471:   { FRBITS (filled_square_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
  472:   { FRBITS (hollow_square_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
  473:   { FRBITS (vertical_bar_bits),       8, 0, ALIGN_BITMAP_CENTER, 0 },
  474:   { FRBITS (horizontal_bar_bits),     8, 0, ALIGN_BITMAP_BOTTOM, 0 },
  475:   { FRBITS (empty_line_bits),         8, 3, ALIGN_BITMAP_TOP,    0 },
  476: };
  477: 
  478: #define NO_FRINGE_BITMAP 0
  479: #define UNDEF_FRINGE_BITMAP 1
  480: #define MAX_STANDARD_FRINGE_BITMAPS (sizeof(standard_bitmaps)/sizeof(standard_bitmaps[0]))
  481: 
  482: static struct fringe_bitmap **fringe_bitmaps;
  483: static Lisp_Object *fringe_faces;
  484: static int max_fringe_bitmaps;
  485: 
  486: static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
  487: 
  488: 
  489: /* Lookup bitmap number for symbol BITMAP.
  490:    Return 0 if not a bitmap.  */
  491: 
  492: int
  493: lookup_fringe_bitmap (bitmap)
  494:      Lisp_Object bitmap;
  495: {
  496:   int bn;
  497: 
  498:   bitmap = Fget (bitmap, Qfringe);
  499:   if (!INTEGERP (bitmap))
  500:     return 0;
  501: 
  502:   bn = XINT (bitmap);
  503:   if (bn > NO_FRINGE_BITMAP
  504:       && bn < max_used_fringe_bitmap
  505:       && (bn < MAX_STANDARD_FRINGE_BITMAPS
  506:           || fringe_bitmaps[bn] != NULL))
  507:     return bn;
  508: 
  509:   return 0;
  510: }
  511: 
  512: /* Get fringe bitmap name for bitmap number BN.
  513: 
  514:    Found by traversing Vfringe_bitmaps comparing BN to the
  515:    fringe property for each symbol.
  516: 
  517:    Return BN if not found in Vfringe_bitmaps.  */
  518: 
  519: static Lisp_Object
  520: get_fringe_bitmap_name (bn)
  521:      int bn;
  522: {
  523:   Lisp_Object bitmaps;
  524:   Lisp_Object num;
  525: 
  526:   /* Zero means no bitmap -- return nil.  */
  527:   if (bn <= 0)
  528:     return Qnil;
  529: 
  530:   bitmaps = Vfringe_bitmaps;
  531:   num = make_number (bn);
  532: 
  533:   while (CONSP (bitmaps))
  534:     {
  535:       Lisp_Object bitmap = XCAR (bitmaps);
  536:       if (EQ (num, Fget (bitmap, Qfringe)))
  537:         return bitmap;
  538:       bitmaps = XCDR (bitmaps);
  539:     }
  540: 
  541:   return num;
  542: }
  543: 
  544: 
  545: /* Draw the bitmap WHICH in one of the left or right fringes of
  546:    window W.  ROW is the glyph row for which to display the bitmap; it
  547:    determines the vertical position at which the bitmap has to be
  548:    drawn.
  549:    LEFT_P is 1 for left fringe, 0 for right fringe.
  550: */
  551: 
  552: static void
  553: draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
  554:      struct window *w;
  555:      struct glyph_row *row;
  556:      int left_p, overlay;
  557:      int which;
  558: {
  559:   struct frame *f = XFRAME (WINDOW_FRAME (w));
  560:   struct draw_fringe_bitmap_params p;
  561:   struct fringe_bitmap *fb;
  562:   int period;
  563:   int face_id = DEFAULT_FACE_ID;
  564: 
  565:   p.cursor_p = 0;
  566:   p.overlay_p = (overlay & 1) == 1;
  567:   p.cursor_p = (overlay & 2) == 2;
  568: 
  569:   if (which != NO_FRINGE_BITMAP)
  570:     {
  571:     }
  572:   else if (left_p)
  573:     {
  574:       which = row->left_fringe_bitmap;
  575:       face_id = row->left_fringe_face_id;
  576:     }
  577:   else
  578:     {
  579:       which = row->right_fringe_bitmap;
  580:       face_id = row->right_fringe_face_id;
  581:     }
  582: 
  583:   if (face_id == DEFAULT_FACE_ID)
  584:     {
  585:       Lisp_Object face;
  586: 
  587:       if ((face = fringe_faces[which], NILP (face))
  588:           || (face_id = lookup_derived_face (f, face, 'A', FRINGE_FACE_ID, 0),
  589:               face_id < 0))
  590:         face_id = FRINGE_FACE_ID;
  591:     }
  592: 
  593:   fb = fringe_bitmaps[which];
  594:   if (fb == NULL)
  595:     fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
  596:                            ? which : UNDEF_FRINGE_BITMAP];
  597: 
  598:   period = fb->period;
  599: 
  600:   /* Convert row to frame coordinates.  */
  601:   p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
  602: 
  603:   p.which = which;
  604:   p.bits = fb->bits;
  605:   p.wd = fb->width;
  606: 
  607:   p.h = fb->height;
  608:   p.dh = (period > 0 ? (p.y % period) : 0);
  609:   p.h -= p.dh;
  610:   /* Clip bitmap if too high.  */
  611:   if (p.h > row->height)
  612:     p.h = row->height;
  613: 
  614:   p.face = FACE_FROM_ID (f, face_id);
  615: 
  616:   if (p.face == NULL)
  617:     {
  618:       /* This could happen after clearing face cache.
  619:          But it shouldn't happen anymore.  ++kfs */
  620:       return;
  621:     }
  622: 
  623:   PREPARE_FACE_FOR_DISPLAY (f, p.face);
  624: 
  625:   /* Clear left fringe if no bitmap to draw or if bitmap doesn't fil