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 }