-xr_line (struct outp_driver *this,
- int x0, int y0, int x3, int y3,
- enum outp_line_style top, enum outp_line_style left,
- enum outp_line_style bottom, enum outp_line_style right)
-{
- /* The algorithm here is somewhat subtle, to allow it to handle
- all the kinds of intersections that we need.
-
- Three additional ordinates are assigned along the x axis. The
- first is xc, midway between x0 and x3. The others are x1 and
- x2; for a single vertical line these are equal to xc, and for
- a double vertical line they are the ordinates of the left and
- right half of the double line.
-
- yc, y1, and y2 are assigned similarly along the y axis.
-
- The following diagram shows the coordinate system and output
- for double top and bottom lines, single left line, and no
- right line:
-
- x0 x1 xc x2 x3
- y0 ________________________
- | # # |
- | # # |
- | # # |
- | # # |
- | # # |
- y1 = y2 = yc |######### # |
- | # # |
- | # # |
- | # # |
- | # # |
- y3 |________#_____#_______|
- */
- struct xr_driver_ext *ext = this->ext;
-
- /* Offset from center of each line in a pair of double lines. */
- int double_line_ofs = (ext->line_space + ext->line_width) / 2;
-
- /* Are the lines along each axis single or double?
- (It doesn't make sense to have different kinds of line on the
- same axis, so we don't try to gracefully handle that case.) */
- bool double_vert = top == OUTP_L_DOUBLE || bottom == OUTP_L_DOUBLE;
- bool double_horz = left == OUTP_L_DOUBLE || right == OUTP_L_DOUBLE;
-
- /* When horizontal lines are doubled,
- the left-side line along y1 normally runs from x0 to x2,
- and the right-side line along y1 from x3 to x1.
- If the top-side line is also doubled, we shorten the y1 lines,
- so that the left-side line runs only to x1,
- and the right-side line only to x2.
- Otherwise, the horizontal line at y = y1 below would cut off
- the intersection, which looks ugly:
- x0 x1 x2 x3
- y0 ________________________
- | # # |
- | # # |
- | # # |
- | # # |
- y1 |######### ########|
- | |
- | |
- y2 |######################|
- | |
- | |
- y3 |______________________|
- It is more of a judgment call when the horizontal line is
- single. We actually choose to cut off the line anyhow, as
- shown in the first diagram above.
- */
- bool shorten_y1_lines = top == OUTP_L_DOUBLE;
- bool shorten_y2_lines = bottom == OUTP_L_DOUBLE;
- bool shorten_yc_line = shorten_y1_lines && shorten_y2_lines;
- int horz_line_ofs = double_vert ? double_line_ofs : 0;
- int xc = (x0 + x3) / 2;
- int x1 = xc - horz_line_ofs;
- int x2 = xc + horz_line_ofs;
-
- bool shorten_x1_lines = left == OUTP_L_DOUBLE;
- bool shorten_x2_lines = right == OUTP_L_DOUBLE;
- bool shorten_xc_line = shorten_x1_lines && shorten_x2_lines;
- int vert_line_ofs = double_horz ? double_line_ofs : 0;
- int yc = (y0 + y3) / 2;
- int y1 = yc - vert_line_ofs;
- int y2 = yc + vert_line_ofs;
-
- if (!double_horz)
- horz_line (this, x0, x1, x2, x3, yc, left, right, shorten_yc_line);
- else
- {
- horz_line (this, x0, x1, x2, x3, y1, left, right, shorten_y1_lines);
- horz_line (this, x0, x1, x2, x3, y2, left, right, shorten_y2_lines);
- }