File indexing completed on 2024-04-28 05:46:48

0001 /*****************************************************************************
0002  *   Copyright 2003 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
0003  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0004  *                                                                           *
0005  *   This program is free software; you can redistribute it and/or modify    *
0006  *   it under the terms of the GNU Lesser General Public License as          *
0007  *   published by the Free Software Foundation; either version 2.1 of the    *
0008  *   License, or (at your option) version 3, or any later version accepted   *
0009  *   by the membership of KDE e.V. (or its successor approved by the         *
0010  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0011  *   Section 6 of version 3 of the license.                                  *
0012  *                                                                           *
0013  *   This program is distributed in the hope that it will be useful,         *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0016  *   Lesser General Public License for more details.                         *
0017  *                                                                           *
0018  *   You should have received a copy of the GNU Lesser General Public        *
0019  *   License along with this library. If not,                                *
0020  *   see <http://www.gnu.org/licenses/>.                                     *
0021  *****************************************************************************/
0022 
0023 #include "utils_p.h"
0024 #include <qtcurve-utils/number.h>
0025 
0026 namespace QtCurve {
0027 namespace Rect {
0028 
0029 QTC_EXPORT void
0030 union_(const QtcRect *src1, const QtcRect *src2, QtcRect *dest)
0031 {
0032     // Copied from gdk_rectangle_union
0033     int dest_x = qtcMin(src1->x, src2->x);
0034     int dest_y = qtcMin(src1->y, src2->y);
0035     dest->width = qtcMax(src1->x + src1->width,
0036                          src2->x + src2->width) - dest_x;
0037     dest->height = qtcMax(src1->y + src1->height,
0038                           src2->y + src2->height) - dest_y;
0039     dest->x = dest_x;
0040     dest->y = dest_y;
0041 }
0042 
0043 QTC_EXPORT bool
0044 intersect(const QtcRect *src1, const QtcRect *src2, QtcRect *dest)
0045 {
0046     // Copied from gdk_rectangle_intersect
0047     int dest_x = qtcMax(src1->x, src2->x);
0048     int dest_y = qtcMax(src1->y, src2->y);
0049     int dest_x2 = qtcMin(src1->x + src1->width, src2->x + src2->width);
0050     int dest_y2 = qtcMin(src1->y + src1->height, src2->y + src2->height);
0051 
0052     if (dest_x2 > dest_x && dest_y2 > dest_y) {
0053         if (dest) {
0054             dest->x = dest_x;
0055             dest->y = dest_y;
0056             dest->width = dest_x2 - dest_x;
0057             dest->height = dest_y2 - dest_y;
0058         }
0059         return true;
0060     } else if (dest) {
0061         dest->width = 0;
0062         dest->height = 0;
0063     }
0064     return false;
0065 }
0066 
0067 }
0068 
0069 namespace Cairo {
0070 
0071 QTC_EXPORT void
0072 pathPoints(cairo_t *cr, const GdkPoint *pts, int count)
0073 {
0074     // The (0.5, 0.5) offset here is for moving the path to the center of the
0075     // pixel.
0076     cairo_move_to(cr, pts[0].x + 0.5, pts[0].y + 0.5);
0077     for (int i = 1;i < count;i++) {
0078         cairo_line_to(cr, pts[i].x + 0.5, pts[i].y + 0.5);
0079     }
0080 }
0081 
0082 static void
0083 pathRegion(cairo_t *cr, const cairo_region_t *region)
0084 {
0085     // Copied from gdk_cairo_region.
0086     int n_boxes = cairo_region_num_rectangles(region);
0087     QtcRect box;
0088     for (int i = 0;i < n_boxes;i++) {
0089         cairo_region_get_rectangle(region, i, &box);
0090         cairo_rectangle(cr, box.x, box.y, box.width, box.height);
0091     }
0092 }
0093 
0094 QTC_EXPORT void
0095 clipRegion(cairo_t *cr, const cairo_region_t *region)
0096 {
0097     cairo_new_path(cr);
0098     if (qtcLikely(region)) {
0099         pathRegion(cr, region);
0100         cairo_clip(cr);
0101     }
0102 }
0103 
0104 QTC_EXPORT void
0105 clipRect(cairo_t *cr, const QtcRect *_rect)
0106 {
0107     cairo_new_path(cr);
0108     if (qtcLikely(_rect)) {
0109         cairo_rectangle(cr, _rect->x, _rect->y, _rect->width, _rect->height);
0110         cairo_clip(cr);
0111     }
0112 }
0113 
0114 QTC_EXPORT void
0115 setColor(cairo_t *cr, const GdkColor *col, double a)
0116 {
0117     cairo_set_source_rgba(cr, col->red / 65535.0, col->green / 65535.0,
0118                           col->blue / 65535.0, a);
0119 }
0120 
0121 QTC_EXPORT void
0122 patternAddColorStop(cairo_pattern_t *pt, double offset,
0123                     const GdkColor *col, double a)
0124 {
0125     cairo_pattern_add_color_stop_rgba(pt, offset, col->red / 65535.0,
0126                                       col->green / 65535.0,
0127                                       col->blue / 65535.0, a);
0128 }
0129 
0130 QTC_EXPORT void
0131 pathTopLeft(cairo_t *cr, double xd, double yd, double width,
0132             double height, double radius, ECornerBits round)
0133 {
0134     bool rounded = radius > 0.0;
0135 
0136     if (rounded && round & CORNER_BL) {
0137         cairo_arc(cr, xd + radius, yd + height - radius, radius,
0138                   M_PI * 0.75, M_PI);
0139     } else {
0140         cairo_move_to(cr, xd, yd + height);
0141     }
0142     if (rounded && round & CORNER_TL) {
0143         cairo_arc(cr, xd + radius, yd + radius, radius, M_PI, M_PI * 1.5);
0144     } else {
0145         cairo_line_to(cr, xd, yd);
0146     }
0147     if (rounded && round & CORNER_TR) {
0148         cairo_arc(cr, xd + width - radius, yd + radius,
0149                   radius, M_PI * 1.5, M_PI * 1.75);
0150     } else {
0151         cairo_line_to(cr, xd + width, yd);
0152     }
0153 }
0154 
0155 QTC_EXPORT void
0156 pathBottomRight(cairo_t *cr, double xd, double yd, double width,
0157                 double height, double radius, ECornerBits round)
0158 {
0159     bool rounded = radius > 0.0;
0160 
0161     if (rounded && round & CORNER_TR) {
0162         cairo_arc(cr, xd + width - radius, yd + radius, radius, M_PI * 1.75, 0);
0163     } else {
0164         cairo_move_to(cr, xd + width, yd);
0165     }
0166     if (rounded && round & CORNER_BR) {
0167         cairo_arc(cr, xd + width - radius, yd + height - radius,
0168                   radius, 0, M_PI * 0.5);
0169     } else {
0170         cairo_line_to(cr, xd + width, yd + height);
0171     }
0172     if (rounded && round & CORNER_BL) {
0173         cairo_arc(cr, xd + radius, yd + height - radius,
0174                   radius, M_PI * 0.5, M_PI * 0.75);
0175     } else {
0176         cairo_line_to(cr, xd, yd + height);
0177     }
0178 }
0179 
0180 QTC_EXPORT void
0181 pathWhole(cairo_t *cr, double xd, double yd, double width,
0182           double height, double radius, ECornerBits round)
0183 {
0184     bool rounded = radius > 0.0;
0185 
0186     if (rounded && round & CORNER_TL) {
0187         cairo_move_to(cr, xd + radius, yd);
0188     } else {
0189         cairo_move_to(cr, xd, yd);
0190     }
0191     if (rounded && round & CORNER_TR) {
0192         cairo_arc(cr, xd + width - radius, yd + radius, radius,
0193                   M_PI * 1.5, M_PI * 2);
0194     } else {
0195         cairo_line_to(cr, xd + width, yd);
0196     }
0197     if (rounded && round & CORNER_BR) {
0198         cairo_arc(cr, xd + width - radius, yd + height - radius,
0199                   radius, 0, M_PI * 0.5);
0200     } else {
0201         cairo_line_to(cr, xd + width, yd + height);
0202     }
0203     if (rounded && round & CORNER_BL) {
0204         cairo_arc(cr, xd + radius, yd + height - radius,
0205                   radius, M_PI * 0.5, M_PI);
0206     } else {
0207         cairo_line_to(cr, xd, yd + height);
0208     }
0209     if (rounded && round & CORNER_TL) {
0210         cairo_arc(cr, xd + radius, yd + radius, radius, M_PI, M_PI * 1.5);
0211     } else {
0212         cairo_line_to(cr, xd, yd);
0213     }
0214 }
0215 
0216 }
0217 }