⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 picfuns.pas

📁 矢量图源代码 包括直线文本矩形等等
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit PicFuns;

interface

uses Windows,Classes,Forms,Controls,Graphics,Math,StdCtrls,
  PicConst;

  Function  GetPicKeyState:TShiftState;
  procedure InvalidatePicRect(var ACanvas:TCanvas;dRect: TRect);
  Function  GetCanvasTextWidth(txt:String;Font:TFont;WnotH:Boolean):Integer;
  function  CreateLineRgn(xStart, yStart, xEnd, yEnd: Integer): HRGN;
  function  CreateArcRgn(tl:TPoint;rb:TPoint;arcsp:TPoint;arcep:TPoint): HRGN;
  function  CreatePieRgn(tl:TPoint;rb:TPoint;arcsp:TPoint;arcep:TPoint; arct:Byte): HRGN;
  function  PointToCirclePoint(StartPoint:TPoint;EndPoint:TPoint;APoint:TPoint): TPoint;
  function  GetRectMaxFontSize(dRect:TRect;Text:String;Font:TFont;Flagtag:Integer):Integer;



implementation

Function  GetPicKeyState:TShiftState;
begin
  Result := [];
  if GetKeyState(VK_SHIFT) < 0 then Result := Result + [ssShift];
  if GetKeyState(VK_CONTROL) < 0 then  Result := Result + [ssCtrl];
  if GetKeyState(VK_MENU) < 0 then Result := Result + [ssAlt];
end;

procedure InvalidatePicRect(var ACanvas:TCanvas; dRect: TRect);
var
  pp: array[1..2] of TPoint;
  updateRect: TRect;
begin
  with dRect do begin
    pp[1].x := Left - 2 * FOCUS_SIZE;
    pp[1].y := Top - 2 * FOCUS_SIZE;
    pp[2].x := Right + 2 * FOCUS_SIZE;
    pp[2].y := Bottom + 2 * FOCUS_SIZE;
  end;
  with updateRect do begin //增大区域,以保证焦点矩形框被清除
    Left := pp[1].x - 2 * FOCUS_SIZE;
    Top := pp[1].y - 2 * FOCUS_SIZE;
    right := pp[2].x + 2 * FOCUS_SIZE;
    Bottom := pp[2].y + 2 * FOCUS_SIZE;
  end;
  ACanvas.Brush.Color:=clBlack;
  ACanvas.Brush.Style:=bsSolid;
  ACanvas.FillRect(updateRect);
end;

Function  GetCanvasTextWidth(txt:String;Font:TFont;WnotH:Boolean):Integer;
var
  bt:TBitMap;
begin
  bt:=TBitMap.Create;
  try
    bt.Canvas.Font.Assign(Font);
    if WnotH then Result:=bt.Canvas.TextWidth(txt)+2 else Result:=bt.Canvas.TextHeight(Txt)+2; 
  finally
    bt.Free;
  end;
end;


function CreateLineRgn(xStart, yStart, xEnd, yEnd: Integer): HRGN;
var
  xTemp, yTemp: Integer; //交换起点、终点时使用
  diffDistance: Integer; //偏移量
  pp: array[1..4] of TPoint;
begin
  if xStart = xEnd then
    Inc(xEnd);
  if yStart = yEnd then
    Inc(yEnd);
  diffDistance := 5;
  if abs(yStart - yEnd) > diffDistance then //直线比较垂直,沿x方向偏移
  begin
    //调整直线的点的位置,保证yEnd >=yStart
    xTemp := xStart;
    yTemp := yStart;
    if yStart >= yEnd then
    begin
      xStart := xEnd;
      yStart := yEnd;
      xEnd := xTemp;
      yEnd := yTemp;
    end;
    //四边形的四个顶点赋值
    pp[1].x := xStart - diffDistance;
    pp[1].y := yStart;
    pp[2].x := xStart + diffDistance;
    pp[2].y := yStart;
    pp[3].x := xEnd + diffDistance;
    pp[3].y := yEnd;
    pp[4].x := xEnd - diffDistance;
    pp[4].y := yEnd;
  end
  else //直线比较水平,沿y方向偏移
  begin
    //调整直线的点的位置,保证XEnd >=XStart
    xTemp := xStart;
    yTemp := yStart;
    if xStart >= xEnd then
    begin
      xStart := xEnd;
      yStart := yEnd;
      xEnd := xTemp;
      yEnd := yTemp;
    end;
    pp[1].x := xStart;
    pp[1].y := yStart - diffDistance;
    pp[2].x := xStart;
    pp[2].y := yStart + diffDistance;
    pp[3].x := xEnd;
    pp[3].y := yEnd + diffDistance;
    pp[4].x := xEnd;
    pp[4].y := yEnd - diffDistance;
  end;
  Result := createPolygonRgn(pp[1], 4, ALTERNATE);
end;

function  CreateArcRgn(tl:TPoint;rb:TPoint;arcsp:TPoint;arcep:TPoint): HRGN;
var
  centerPoint: TPoint; //圆心
  asp: Single; //细长比
  smallRadius, bigRadius: Integer; //内外圆半径
  radiusY: Integer; //Y向半径
  diffRadius: Integer; //内外半径之差
  arcToPolyAngle: Single; //圆弧转换成多边形的角度
  arcToPolyNumber: Integer; //圆弧转换成多边形的边数
  arcVertexPoint: array of TPoint; //多边形的顶点
  startAngle, endAngle: Single; //起点和终点的夹角
  dx, dy: Integer; //坐标之差
  aa: Single; //临时角度
  i, j: Integer; //循环变量
begin
  //初始化参数
  diffRadius := 5;
  arcToPolyAngle := 5.0 * PI / 180;
  //圆心
  centerPoint.x := (rb.X + tl.X) div 2;
  centerPoint.y := (tl.Y + rb.Y) div 2;
  //Y向半径
  radiusY := abs(rb.Y - tl.Y) div 2;
  //细长比
  asp := abs((rb.X - tl.X) / (rb.Y - tl.Y));
  //****** 计算角度 ******
   //起点角度
  dx := Arcsp.X - centerPoint.x;
  dy := Arcsp.Y - centerPoint.y;
  //起点角度的绝对值
  if dx = 0 then  startAngle := PI / 2  else startAngle := Abs(ArcTan(dy / dx * asp));
  //确定起点角度的大小
  if (dx > 0) and (dy < 0) then
    startAngle := startAngle
  else if (dx < 0) and (dy < 0) then
    startAngle := PI - startAngle
  else if (dx < 0) and (dy > 0) then
    startAngle := PI + startAngle
  else
    startAngle := PI + PI - startAngle;
  //终点角度
  dx := arcep.X - centerPoint.x;
  dy := arcep.Y - centerPoint.y;
  //终点角度绝对值
  if dx = 0 then endAngle := PI / 2 else endAngle := Abs(ArcTan(dy / dx * asp));
  //确定终点角度的大小
  if (dx > 0) and (dy < 0) then
    endAngle := endAngle
  else if (dx < 0) and (dy < 0) then
    endAngle := PI - endAngle
  else if (dx < 0) and (dy > 0) then
    endAngle := PI + endAngle
  else
    endAngle := PI + PI - endAngle;
  //计算内外圆
  smallRadius := radiusY - diffRadius;
  bigRadius := radiusY + diffRadius;
  //计算顶点数
  if endAngle < startAngle then begin //终点角度小于起点角度
    arcToPolyNumber := Trunc((2 * PI + (endAngle - startAngle)) / arcToPolyAngle) + 2;
  end else begin //终点角度大于起点角度
    arcToPolyNumber := Trunc((endAngle - startAngle) / arcToPolyAngle) + 2;
  end;
  //设置顶点数组
  SetLength(arcVertexPoint, 2 * arcToPolyNumber + 2);
  //计算外圆
  for i := 1 to arcToPolyNumber - 1 do begin
    aa := startAngle + (i - 1) * arcToPolyAngle;
    arcVertexPoint[i].x := Round(centerPoint.x + bigRadius * cos(aa) * asp);
    arcVertexPoint[i].y := Round(centerPoint.y - bigRadius * sin(aa));
  end;
  arcVertexPoint[arcToPolyNumber].x := Round(centerPoint.x + bigRadius * Cos(endAngle) * asp);
  arcVertexPoint[arcToPolyNumber].y := Round(centerPoint.y - bigRadius *  Sin(endAngle));
  //计算内圆
  j := 1;
  arcVertexPoint[arcToPolyNumber + j].x := Round(centerPoint.x + smallRadius * Cos(endAngle) * asp);
  arcVertexPoint[arcToPolyNumber + j].y := Round(centerPoint.y - smallRadius * Sin(endAngle));
  for i := arcToPolyNumber - 1 downto 1 do begin
    Inc(j);
    aa := startAngle + (i - 1) * arcToPolyAngle;
    arcVertexPoint[arcToPolyNumber + j].x := Round(centerPoint.x + smallRadius * cos(aa) * asp);
    arcVertexPoint[arcToPolyNumber + j].y := Round(centerPoint.y - smallRadius * sin(aa));
  end;
  arcVertexPoint[2 * arcToPolyNumber + 1] := arcVertexPoint[1];
  arcVertexPoint[2 * arcToPolyNumber + 1].x := arcVertexPoint[1].x;
  arcVertexPoint[2 * arcToPolyNumber + 1].y := arcVertexPoint[1].y;
  for i := 0 to 2 * arcToPolyNumber do arcVertexPoint[i] := arcVertexPoint[i + 1];
  Result := createPolygonRgn(arcVertexPoint[0], 2 * arcToPolyNumber, ALTERNATE);
end;

function CreatePieRgn(tl:TPoint;rb:TPoint;arcsp:TPoint;arcep:TPoint; arct:Byte): HRGN;
//arcShape =1 Chord  arcShape =2 pie
var
  centerPoint: TPoint; //圆心
  asp: Single; //细长比
  bigRadius: Integer; //外圆半径
  radiusY: Integer; //Y向半径
  diffRadius: Integer; //内外半径之差

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -