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 + -
显示快捷键?