def OnPaint_1(hwnd, msg, wp, lp): dc, ps = win32gui.BeginPaint(hwnd) win32gui.SetGraphicsMode(dc, win32con.GM_ADVANCED) br = win32gui.CreateSolidBrush(win32api.RGB(255, 0, 0)) win32gui.SelectObject(dc, br) angle = win32gui.GetWindowLong(hwnd, win32con.GWL_USERDATA) win32gui.SetWindowLong(hwnd, win32con.GWL_USERDATA, angle + 2) r_angle = angle * (math.pi / 180) win32gui.SetWorldTransform( dc, { 'M11': math.cos(r_angle), 'M12': math.sin(r_angle), 'M21': math.sin(r_angle) * -1, 'M22': math.cos(r_angle), 'Dx': 250, 'Dy': 250 }) win32gui.MoveToEx(dc, 250, 250) win32gui.BeginPath(dc) win32gui.Pie(dc, 10, 70, 200, 200, 350, 350, 75, 10) win32gui.Chord(dc, 200, 200, 850, 0, 350, 350, 75, 10) win32gui.LineTo(dc, 300, 300) win32gui.LineTo(dc, 100, 20) win32gui.LineTo(dc, 20, 100) win32gui.LineTo(dc, 400, 0) win32gui.LineTo(dc, 0, 400) win32gui.EndPath(dc) win32gui.StrokeAndFillPath(dc) win32gui.EndPaint(hwnd, ps) return 0
def drawRightArc(self, hdc, pos, radius, width, span, percent, color=ColorCode.BLACK): if percent > 0.0: # Get arc center coordinates xc = pos[0] yc = pos[1] # Calculate a2 a1 = math.radians(span / 2) a2 = math.asin(radius * math.sin(a1) / (radius + width)) # calculate displacement on x and y axis dx = radius * math.cos(a2) dy = radius * math.sin(a2) # calculate starting point coordinates xs = int(xc + dx) ys = int(yc + dy) a2d = math.degrees(a2) # determines arc span span = 2 * a2d # sets the percentage to be drawn n = percent # sets arc fill color sb = win32gui.CreateSolidBrush(color) win32gui.SelectObject(hdc, sb) # sets arc stroke sp = win32gui.CreatePen(win32con.PS_SOLID, 1, ColorCode.BLACK) win32gui.SelectObject(hdc, sp) # draws the outline of the arc win32gui.BeginPath(hdc) win32gui.MoveToEx(hdc, xs, ys) win32gui.AngleArc(hdc, xc, yc, radius + width, -a2d, int(n * span)) win32gui.AngleArc(hdc, xc, yc, radius, int(a2d - (1 - n) * span), -int(n * span)) win32gui.EndPath(hdc) # fills the arc with outer stroke win32gui.StrokeAndFillPath(hdc) # returns the next arc span and radius return span, (radius + width) else: # if its not drawn, returns original arc span and radius return span, radius
def text_to_shape(self, text: str) -> Shape: if sys.platform == "win32": # TODO: Calcultating distance between origins of character cells (just in case of spacing) # Add path to device context win32gui.BeginPath(self.dc) win32gui.ExtTextOut(self.dc, 0, 0, 0x0, None, text) win32gui.EndPath(self.dc) # Getting Path produced by Microsoft API points, type_points = win32gui.GetPath(self.dc) # Checking for errors if len(points) == 0 or len(points) != len(type_points): raise RuntimeError( "This should never happen: function win32gui.GetPath has returned something unexpected.\nPlease report this to the developer" ) # Defining variables shape, last_type = [], None mult_x, mult_y = self.downscale * self.xscale, self.downscale * self.yscale # Convert points to shape i = 0 while i < len(points): cur_point, cur_type = points[i], type_points[i] if cur_type == win32con.PT_MOVETO: if last_type != win32con.PT_MOVETO: # Avoid repetition of command tags shape.append("m") last_type = cur_type shape.extend([ Shape.format_value(cur_point[0] * mult_x), Shape.format_value(cur_point[1] * mult_y), ]) i += 1 elif cur_type == win32con.PT_LINETO or cur_type == ( win32con.PT_LINETO | win32con.PT_CLOSEFIGURE): if last_type != win32con.PT_LINETO: # Avoid repetition of command tags shape.append("l") last_type = cur_type shape.extend([ Shape.format_value(cur_point[0] * mult_x), Shape.format_value(cur_point[1] * mult_y), ]) i += 1 elif cur_type == win32con.PT_BEZIERTO or cur_type == ( win32con.PT_BEZIERTO | win32con.PT_CLOSEFIGURE): if last_type != win32con.PT_BEZIERTO: # Avoid repetition of command tags shape.append("b") last_type = cur_type shape.extend([ Shape.format_value(cur_point[0] * mult_x), Shape.format_value(cur_point[1] * mult_y), Shape.format_value(points[i + 1][0] * mult_x), Shape.format_value(points[i + 1][1] * mult_y), Shape.format_value(points[i + 2][0] * mult_x), Shape.format_value(points[i + 2][1] * mult_y), ]) i += 3 else: # If there is an invalid type -> skip, for safeness i += 1 # Clear device context path win32gui.AbortPath(self.dc) return Shape(" ".join(shape)) elif sys.platform == "linux" or sys.platform == "darwin": # Defining variables shape, last_type = [], None def shape_from_text(new_text, x_add): nonlocal shape, last_type self.layout.set_markup( f"<span " f'strikethrough="{str(self.strikeout).lower()}" ' f'underline="{"single" if self.underline else "none"}"' f">" f"{html.escape(new_text)}" f"</span>", -1, ) self.context.save() self.context.scale( self.downscale * self.xscale * self.fonthack_scale, self.downscale * self.yscale * self.fonthack_scale, ) PangoCairo.layout_path(self.context, self.layout) self.context.restore() path = self.context.copy_path() # Convert points to shape for current_entry in path: current_type = current_entry[0] current_path = current_entry[1] if current_type == 0: # MOVE_TO if last_type != current_type: # Avoid repetition of command tags shape.append("m") last_type = current_type shape.extend([ Shape.format_value(current_path[0] + x_add), Shape.format_value(current_path[1]), ]) elif current_type == 1: # LINE_TO if last_type != current_type: # Avoid repetition of command tags shape.append("l") last_type = current_type shape.extend([ Shape.format_value(current_path[0] + x_add), Shape.format_value(current_path[1]), ]) elif current_type == 2: # CURVE_TO if last_type != current_type: # Avoid repetition of command tags shape.append("b") last_type = current_type shape.extend([ Shape.format_value(current_path[0] + x_add), Shape.format_value(current_path[1]), Shape.format_value(current_path[2] + x_add), Shape.format_value(current_path[3]), Shape.format_value(current_path[4] + x_add), Shape.format_value(current_path[5]), ]) self.context.new_path() curr_width = 0 for i, char in enumerate(text): shape_from_text(char, curr_width + self.hspace * self.xscale * i) curr_width += self.get_text_extents(char)[0] return Shape(" ".join(shape)) else: raise NotImplementedError