drawing.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 1,006 行 · 第 1/3 页
C
1,006 行
/* Classic Ladder Project *//* Copyright (C) 2001-2006 Marc Le Douarain *//* http://www.multimania.com/mavati/classicladder *//* http://www.sourceforge.net/projects/classicladder *//* February 2001 *//* ----------- *//* Draw a rung *//* ----------- *//* This library is free software; you can redistribute it and/or *//* modify it under the terms of the GNU Lesser General Public *//* License as published by the Free Software Foundation; either *//* version 2.1 of the License, or (at your option) any later version. *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *//* Lesser General Public License for more details. *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <gtk/gtk.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include "classicladder.h"#include "global.h"#include "arithm_eval.h"#include "classicladder_gtk.h"#include "edit.h"#ifdef SEQUENTIAL_SUPPORT#include "drawing_sequential.h"#endif#include "symbols.h"#include "drawing.h"#ifdef GTK2#include <pango/pango.h>#endifchar * DisplayInfo(int Type, int Offset){ static char Buffer[20]; switch(Type) { case VAR_MEM_BIT: sprintf(Buffer,"%cB%d",'%',Offset); break; case VAR_TIMER_DONE: sprintf(Buffer,"%cT%d.D",'%',Offset); break; case VAR_TIMER_RUNNING: sprintf(Buffer,"%cT%d.R",'%',Offset); break; case VAR_MONOSTABLE_RUNNING: sprintf(Buffer,"%cM%d.R",'%',Offset); break; case VAR_COUNTER_DONE: sprintf(Buffer,"%cC%d.D",'%',Offset); break; case VAR_COUNTER_EMPTY: sprintf(Buffer,"%cC%d.E",'%',Offset); break; case VAR_COUNTER_FULL: sprintf(Buffer,"%cC%d.F",'%',Offset); break; case VAR_STEP_ACTIVITY: sprintf(Buffer,"%cX%d",'%',Offset); break; case VAR_PHYS_INPUT: sprintf(Buffer,"%cI%d",'%',Offset); break; case VAR_PHYS_OUTPUT: sprintf(Buffer,"%cQ%d",'%',Offset); break; case VAR_MEM_WORD: sprintf(Buffer,"%cW%d",'%',Offset); break; case VAR_STEP_TIME: sprintf(Buffer,"%cX%d.V",'%',Offset); break; case VAR_TIMER_PRESET: sprintf(Buffer,"%cT%d.P",'%',Offset); break; case VAR_TIMER_VALUE: sprintf(Buffer,"%cT%d.V",'%',Offset); break; case VAR_MONOSTABLE_PRESET: sprintf(Buffer,"%cM%d.P",'%',Offset); break; case VAR_MONOSTABLE_VALUE: sprintf(Buffer,"%cM%d.V",'%',Offset); break; case VAR_COUNTER_PRESET: sprintf(Buffer,"%cC%d.P",'%',Offset); break; case VAR_COUNTER_VALUE: sprintf(Buffer,"%cC%d.V",'%',Offset); break; default: sprintf(Buffer,"???"); break; } if ( InfosGene->DisplaySymbols ) { // verify if a symbol has been defined for the variable... char * Symbol = ConvVarNameToSymbol( Buffer ); if ( Symbol!=NULL ) return Symbol; } return Buffer;}char * DisplayArithmExpr(char * Expr,int NumCarMax){ static char Buffer[ARITHM_EXPR_SIZE+30]; char * Ptr = Expr; int Fill = 0; Buffer[0] = '\0'; /* null expression ? */ if (Expr[0]=='\0') return Buffer; do { /* start of a variable ? */ if (*Ptr=='@') { int NumVar,TypeVar; char VarBuffer[20]; if (IdentifyVariable(Ptr,&NumVar,&TypeVar)) strcpy(VarBuffer,DisplayInfo(NumVar,TypeVar)); else strcpy(VarBuffer,"??"); strcpy(&Buffer[Fill],VarBuffer); /* flush until end of a variable */ do { Ptr++; } while(*Ptr!='@'); Ptr++; Fill = Fill+strlen(VarBuffer); } else { Buffer[Fill++] = *Ptr++; } } while(*Ptr!='\0'); Buffer[Fill] = '\0'; /* size limited ? */ if (NumCarMax>0) { if (strlen(Buffer)>NumCarMax) { Buffer[NumCarMax-1] = '.'; Buffer[NumCarMax] = '.'; Buffer[NumCarMax+1] = '\0'; } } return Buffer;}#ifdef GTK2/* Drawing text centered with GTK2. *//* if Height is -1, then drawing on top of BaseY given... */void DrawTextWithOffsetGTK2( GdkPixmap * DrawPixmap, GdkGC * GcRef, int BaseX, int BaseY, int Width, int Height, char * Text, int BorderOffset ) { PangoLayout * playout = gtk_widget_create_pango_layout ( GTK_WIDGET(drawing_area), Text ); int SizeX, SizeY, OffsetX,PosiY; pango_layout_set_width( playout, Width*PANGO_SCALE ); pango_layout_get_pixel_size( playout, &SizeX, &SizeY ); OffsetX = 0; if ( Width>0 ) { OffsetX = (Width-SizeX -BorderOffset*2)/2; if ( OffsetX<=BorderOffset ) OffsetX = BorderOffset; } PosiY = BaseY - SizeY; //BaseY is the bottom if Height is -1. if ( Height>0 ) { PosiY = BaseY + (Height-SizeY)/2; // too much text ? if ( SizeY>= Height ) { int NbrLines = pango_layout_get_line_count( playout ); int HeightOneLine = SizeY/NbrLines; int NbrLinesToDisplay = Height/HeightOneLine;//printf("overflow text display: NbrLines=%d, HeightOneLine=%d, NbrLinesToDisplay=%d\n", NbrLines, HeightOneLine, NbrLinesToDisplay); if ( NbrLinesToDisplay>1 ) { PangoLayoutLine * playout_line = pango_layout_get_line( playout, NbrLinesToDisplay-1 ); if ( playout_line!=NULL ) { char * BuffTmp = malloc( strlen(Text)+1 ); if ( BuffTmp ) { char * pScanText; strcpy( BuffTmp, Text );//printf("playout_line start=%d length=%d\n", playout_line->start_index, playout_line->length );//printf("playout_line string=%s\n", &Text[ playout_line->start_index+playout_line->length ]); pScanText = &BuffTmp[ playout_line->start_index+playout_line->length-1 ]; *pScanText--='\0'; *pScanText--='.'; *pScanText--='.'; *pScanText--='.'; pango_layout_set_text( playout, BuffTmp, -1 ); pango_layout_get_pixel_size( playout, &SizeX, &SizeY ); PosiY = BaseY - SizeY; //BaseY is the bottom if Height is -1. if ( Height>0 ) PosiY = BaseY + (Height-SizeY)/2; free( BuffTmp ); } } } } } gdk_draw_layout (DrawPixmap, GcRef, BaseX+OffsetX,PosiY, playout); g_object_unref (playout);}void DrawTextGTK2( GdkPixmap * DrawPixmap, GdkGC * GcRef, int BaseX, int BaseY, int Width, int Height, char * Text ) { DrawTextWithOffsetGTK2( DrawPixmap, GcRef, BaseX, BaseY, Width, Height, Text, 0/*BorderOffset*/ );}#endifvoid DrawCommonElementForToolbar(GdkPixmap * DrawPixmap,int x,int y,int Size,int NumElement){ int SizeDiv2 = Size/2; int SizeDiv3 = Size/3; int SizeDiv4 = Size/4; switch(NumElement) { case EDIT_POINTER: gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+SizeDiv4,y+SizeDiv4, x+Size-SizeDiv4,y+Size-SizeDiv4); /* \ */ gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+SizeDiv4,y+SizeDiv4, x+SizeDiv3,y+SizeDiv2); /* | */ gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+SizeDiv4,y+SizeDiv4, x+SizeDiv2,y+SizeDiv3); /* _ */ gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+SizeDiv3,y+SizeDiv2, x+SizeDiv2,y+SizeDiv3); break; case EDIT_ERASER: gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+SizeDiv3,y+SizeDiv4, x+Size-SizeDiv4,y+SizeDiv4); gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+SizeDiv4,y+Size-SizeDiv4, x+Size-SizeDiv3,y+Size-SizeDiv4); gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+SizeDiv3,y+SizeDiv4, x+SizeDiv4,y+Size-SizeDiv4); gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+Size-SizeDiv4,y+SizeDiv4, x+Size-SizeDiv3,y+Size-SizeDiv4); gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+SizeDiv4 +2,y+Size-SizeDiv4 +2, x+Size-SizeDiv3 +2,y+Size-SizeDiv4 +2); gdk_draw_line(DrawPixmap, drawing_area->style->black_gc, x+Size-SizeDiv4 +2,y+SizeDiv4 +2, x+Size-SizeDiv3 +2,y+Size-SizeDiv4 +2); break; }}void DrawElement(GdkPixmap * DrawPixmap,int x,int y,int Width,int Height,StrElement Element,char DrawingOption){ char BufTxt[50]; StrTimer * Timer; StrMonostable * Monostable; StrCounter * Counter; int WidDiv2 = Width/2; int WidDiv3 = Width/3; int WidDiv4 = Width/4; int HeiDiv2 = Height/2; int HeiDiv3 = Height/3; int HeiDiv4 = Height/4; GdkGC * DynaGcOff; GdkGC * TheGc; GdkColor DynaGdkColor; GdkGC * DynaGcOn; DynaGdkColor.pixel = 0xFF22FF; DynaGdkColor.red = 0xFF; DynaGdkColor.green = 0x22; DynaGdkColor.blue = 0xFF; DynaGcOn = gdk_gc_new(DrawPixmap); gdk_gc_set_foreground(DynaGcOn,&DynaGdkColor); #ifdef THICK_LINE_ELE_ACTIVATED gdk_gc_set_line_attributes(DynaGcOn, THICK_LINE_ELE_ACTIVATED, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); #endif DynaGcOff = drawing_area->style->black_gc; /* State with color */ TheGc = drawing_area->style->black_gc; if ( (DrawingOption==DRAW_NORMAL) && (!EditDatas.ModeEdit) && (Element.DynamicState) ) TheGc = DynaGcOn; if (EditDatas.ModeEdit || DrawingOption==DRAW_FOR_PRINT) { gdk_gc_unref(DynaGcOn); DynaGcOn = drawing_area->style->black_gc; } /* Drawing - - */ switch(Element.Type) { case ELE_INPUT: case ELE_INPUT_NOT: case ELE_RISING_INPUT: case ELE_FALLING_INPUT: case ELE_OUTPUT: case ELE_OUTPUT_NOT: case ELE_OUTPUT_SET: case ELE_OUTPUT_RESET: case ELE_OUTPUT_JUMP: case ELE_OUTPUT_CALL: gdk_draw_line(DrawPixmap, TheGc, x,y+HeiDiv2, x+WidDiv3,y+HeiDiv2); gdk_draw_line(DrawPixmap, TheGc, x+WidDiv3*2,y+HeiDiv2, x+Width,y+HeiDiv2); } /* Drawing || or () or --- */ switch(Element.Type) { case ELE_INPUT: case ELE_INPUT_NOT: case ELE_RISING_INPUT: case ELE_FALLING_INPUT: gdk_draw_line(DrawPixmap, TheGc, x+WidDiv3,y+HeiDiv4, x+WidDiv3,y+Height-HeiDiv4); gdk_draw_line(DrawPixmap, TheGc, x+WidDiv3*2,y+HeiDiv4, x+WidDiv3*2,y+Height-HeiDiv4); break; case ELE_CONNECTION: gdk_draw_line(DrawPixmap, TheGc, x,y+HeiDiv2, x+Width,y+HeiDiv2);/* gdk_draw_rectangle (DrawPixmap,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?