Jump to content

Paolo

Member
  • Posts

    182
  • Joined

  • Last visited

Posts posted by Paolo

  1. Hello,

    Is there a way to programmatically import an image as png with alpha channel, without showing up the import dialog as in:

    def vs.ImportImageFileN(filePath, importPt, mode):
        return HANDLE

    I am aware of:

    def vs.ImportImageFile(filePath, importPt):
        return HANDLE

    but I am wondering if there is a way to force the default import preferences (JPEG) as PNG with ALPHA channel.

     

    This is needed in my perspective rectifier plugin, where a new image (PNG with ALPHA) is created and imported on the fly.

     

  2. Vectorworks® plugins, symbols and scripts © Paolo Marcuccetti 2020

     

    A collection of digital products for Vectorworks®,

    some for free and some for a fee!

     

    New Barroom symbols

    Bar rooms (full package) includes about 400 symbols 2D/3D, gathered in 11 files  (Vectorworks® 2020).
    These symbols are all originally made by me (based on real objects) in my 20 years experience in the bar room / retail design.
    You can purchase the full package or single packages or even single symbols.

     

    Paid products are sold on:

    https://gumroad.com/pamarcu

     

    image.png

    • Like 2
  3. I am trying to use this function 

    FindFile(whichPath, relFilePath; VAR outPath)

    I am searching for a specific file in Libraries/Defaults, but I want it to be found either in program folder or user folder or any workgroups folder, so the code is:

    resultBoolean := FindFile(14, 'MoouldingsLib.vwx', outPath);

    I have tried it in a document script and it works perfectly, but, while transposing this script in an include file (.vss), where I need it to be, it crashes Vectorworks.

     

    Any suggestion?

    Are there alternative work arounds to get the full path of a file inside Libraries/Defaults, independently if this is in a workgroup or user or program folder?

     

    Thank you for the help.

  4. By popular demand, I have just released a Mouldings plugins DEMO version, so you can evaluate them all and, in case, proceed to buy.

     

    You can download the demo and find more info on Mouldings plugins starting from:

    https://fitplot.it/vwplugins/mouldings.html


    The DEMO plugins do all what the full version does, but they have, of course, some limitations.

    Each time you change a parameter of a Mouldings object, a message shows up, reminding you that you are running the DEMO.

    995083478_Schermata2019-11-29alle16_56_43.thumb.png.f4d5795a22c155bf2fd782e013de38cc.png

    You can exit this dialog clicking the link button to Mouldings page (with the chance to buy) or clicking Close.

    The close button halts execution for 5 seconds, but after that, changes to the object are regularly applied.

     

    Installation…

    1. Unzip the downloaded file.
    2. You get two folders and a pdf (Mouldings plugin IV Manual).
    3. Move the “Mouldings” folder inside your Vectorworks Plug-ins folder.
    4. Move the “Moulding - Models” folder inside Vectorworks Libraries/Defaults folder.
    5. Restart Vectorworks.
    6. Edit your workspace adding the (Mouldings) plugins.

     

    Whenever you'll upgrade to the full version, you’ll just have to replace the two folders above with the new ones I'll send, restart Vectorworks (no need to edit the workspace again) and your saved works will recognise the new plugins seamlessly.

    • Like 2
  5. I am happy to announce the release of Mouldings plugins version IV.

    It includes new parametric objects and a vaste library of profiles.

    Works with Vectorworks 2019 and 2020.

     

    Profile-selection-dialog.thumb.png.071544dd0d0903d6374f0429690ed38b.png

     

    More info on the site at https://fitplot.it/vwplugins/mouldings.html

    Here you can take a look at the Mouldings plugins Manual (Version IV).

    Use the on site form (scroll to bottom) to get in touch.

     

    Here's a short video of the new Frames (array) object suitable for wainscoting, complex doors etc. etc.

     

     

    And here one longer showing other parametric objects in the Mouldings plugins package:

     

    • Like 1
  6. Thank you for your reply.

    I have seen the attached example, but I need something different.

     

    After various tries, I have opted for the image control, though I am not 100% happy because symbols converted in images shows a "2" in the lower right side of the icon (to show that are 2D symbols).

    You can see (in the attached image) the difference between the big tile (obtained with CreateImgFromSymbol) and the smaller tiles (obtained with CreateImageControl).

    It is not what I wish to get from a "Modern Dialog", but I can live with it...

    307960845_Schermata2019-09-10alle20_51_23.thumb.png.c8369ed9cd4278f2732fd68f50f10cf1.png

     

    For those that may be interested, since there are not plenty of examples around, here's the code to get the dialog above (kLib is the path to single files and folders whose name is, as symbols, in the vectorworks file at path symLib.

     

    PROCEDURE Example;
    const
    kLib = '/Applications/Vectorworks 2019 IT/Risorse/Elementi base/Mouldings - Models/Cornices';
    symLib = '/Applications/Vectorworks 2019 IT/Risorse/Elementi base/Mouldings - Models/Cornices/MouldingsLib.vwx';
    
    maxFolders = 1000;
    kTreeControlID = 4;
    kChosenSymbol = 5;
    kChosenText = 6;
    kBackwardBtn = 7;
    kForwardBtn = 8;
    kPages = 9;
    kFirstSymbol = 101;
    kSymbolWidth = 50;
    kRows 			= 6;
    kColumns 		= 7;
    
    
    TYPE
    menuItem = STRUCTURE
    	voce: string;
    	idx : integer;
    END;
    
    VAR
    dialog1 :INTEGER;
    result  :INTEGER;
    widthInChars, heightInChars :INTEGER;
    root1, root2, child1, child2 :INTEGER;
    
    folders : array[0..maxFolders] of menuItem;
    buttons : array[0..maxFolders] of menuItem;
    c, r : integer;
    pagina, numeroPagine, numeroFiles: integer;
    
    function validProfileFile(name: string): boolean;
    begin
    	validProfileFile := Pos('.cpf', name) > 0;
    end;
    
    	
    procedure ricorsione(node: string; livello: integer; previous: integer);
    
    var
    i: integer;
    foldername: string;
    root: integer;
    
    begin
    i := 1;
    
    folderName := GetFilesInFolder(node, 1);
    
    
    WHILE (folderName <> '') DO BEGIN
    
    	{writeln(livello, '. ', i, ' -> ', foldername);}
    	
    	{se è una folder, faccio un altro giro}
    	if Pos('.', folderName) = 0 then 
    	begin {è una cartella}
    		root := InsertTreeControlItem(dialog1, kTreeControlID, folderName, previous, livello);
    
    		folders[root].voce := concat(node, '/', foldername);
    		folders[root].idx := root;
    		
    		ricorsione(concat(node,'/', folderName), livello+1, root);		
    	end;
    		
    	i := i+1;
    	folderName := GetFilesInFolder(node, i);
    END;
    end;
    
    procedure updateDialog;
    var
    j : integer;
    idx : integer;
    
    begin
    			for j := kFirstSymbol+(pagina-1)*kColumns*kRows to kFirstSymbol+(pagina)*kColumns*kRows-1 do
    			begin
                idx := j-(pagina-1)*kColumns*kRows;
    			beginContext;
    			IF CopySymbol(symLib, buttons[j].voce) then 
    				begin
    					Symbol(buttons[j].voce, 0, 0, 0);
    					SetImageControlHandle(dialog1, idx,getObject(buttons[j].voce));
    					SetItemClickable(dialog1, idx, TRUE);
    					EnableItem(dialog1, idx, true);
    					SetHelpText(dialog1, idx,buttons[j].voce);
    					ShowItem(dialog1, idx, true);
    				end else begin
    					SetImageControlHandle(dialog1, idx,nil);
    					SetHelpText(dialog1, idx,'');
    					ShowItem(dialog1, idx, false);
    				end;
    			endContext(0);	
    			end;
    end;
    
    
    
    PROCEDURE Dialog_Handler(VAR item :LONGINT; data :LONGINT);
    var
    result: boolean;
    i,j : integer;
    fileName : string;
    idItem : integer;
    x : integer;
    deltaPagina : integer;
    
    BEGIN
    
    x := item-kFirstSymbol;
    deltaPagina := (pagina-1)*kRows*kColumns;
    
    CASE item OF
    	SetupDialogC:
    		BEGIN
    			ricorsione(klib, 1, -1);
    			updateDialog;
    		END;
    		
    	kTreeControlID : BEGIN
    			{reinizializzo array}
    			for i := 0 to maxFolders do
    			begin
    				buttons[i].voce := '';
    			end;
    			
    			result := GetTreeControlSelectedItem(dialog1, kTreeControlID, idItem);
    			
    			i := 1;
    			j := 0;
    
    			fileName := GetFilesInFolder(folders[idItem].voce, i);
    
    			WHILE (fileName <> '') DO BEGIN
    				{se è un file…}
    				if validProfileFile(fileName) then 
    				begin
    					buttons[kFirstSymbol+j].voce := fileName;
    				
    				end else
    				begin
    					j := j-1;
    				end;
    				j := j+1;
    				i := i+1;
    				fileName := GetFilesInFolder(folders[idItem].voce, i);
    			END;
    			
    			numeroFiles := j;
    			pagina := 1;
    			numeroPagine := trunc(j / (kColumns*kRows))+1;
    			
    			{completo con quelli vuoti}
    			for j := j to kRows*kColumns do
    				begin
    					buttons[kFirstSymbol+j].voce := '';
    				end;
    
    			SetItemText(dialog1, kchosenText, 'choose a symbol');
    			SetItemText(dialog1, kPages, concat(num2str(0, pagina), '/', num2Str(0, numeroPagine)));
    			updateDialog;
    		END;
    		
    	kBackwardBtn : BEGIN
    			pagina := pagina - 1;
    			if pagina < 1 then pagina := numeroPagine;
    			SetItemText(dialog1, kPages, concat(num2str(0, pagina), '/', num2Str(0, numeroPagine)));
    			updateDialog;
    		END;
    	
    	kForwardBtn :BEGIN
    			pagina := pagina + 1;
    			if pagina > numeroPagine then pagina := 1;
    			SetItemText(dialog1, kPages, concat(num2str(0, pagina), '/', num2Str(0, numeroPagine)));
    			updateDialog;
    		END;
    
    	kFirstSymbol..kFirstSymbol+kRows*kColumns: 
    		BEGIN
    			beginContext;
    			IF CopySymbol(symLib, buttons[kFirstSymbol+x+deltaPagina].voce) then Symbol(buttons[kFirstSymbol+x+deltaPagina].voce, 0, 0, 0);
    			updateSymbolDisplayControl(dialog1, kChosenSymbol, buttons[kFirstSymbol+x+deltaPagina].voce, 0, 2);
    			SetHelpText(dialog1, kChosenSymbol,buttons[kFirstSymbol+x+deltaPagina].voce);
    			endContext(0);
    			SetItemText(dialog1, kchosenText, buttons[kFirstSymbol+x+deltaPagina].voce);
    		END;
    
    END;
    END;
    
    
    
    BEGIN
    dialog1 := CreateLayout('Example Dialog', TRUE, 'OK', 'Cancel');
    widthInChars := 28;
    heightInChars := 28;
    CreateTreeControl(dialog1, kTreeControlID, widthInChars, heightInChars);
    SetFirstLayoutItem(dialog1, kTreeControlID);
    
    CreateSymbolDisplayControl(dialog1,  kChosenSymbol, '', kSymbolWidth*3, kSymbolWidth*3, 5 , 0 , 2);
    SetRightItem(dialog1, kTreeControlID, kChosenSymbol,0,0);
    
    CreateStyledStatic(dialog1, kChosenText, 'Chosen symbol', 30,2);
    SetStaticTextColor(dialog1, kchosenText, 256,0,0);
    SetRightItem(dialog1, kChosenSymbol, kChosenText,0,0);
    
    CreatePushButton(dialog1, kBackwardBtn, '<-️︎');
    CreatePushButton(dialog1, kForwardBtn, '->️');
    CreateCenteredStatic(dialog1, kPages, '1/1', 6);
                  
    SetBelowItem(dialog1, kTreeControlID,kBackwardBtn,0,0);
    SetRightItem(dialog1, kBackwardBtn, kPages,0,0);
    SetRightItem(dialog1, kPages, kForwardBtn,0,0);
    
    	for c := 0 to kColumns-1 do
    	for r := 0 to kRows-1 do
    		begin
    		{CreateSymbolDisplayControl(dialog1,  kFirstSymbol+c+kColumns*r, '', kSymbolWidth, kSymbolWidth, 5, 0, 2);}
    		CreateImageControl(dialog1, kFirstSymbol+c+kColumns*r, kSymbolWidth, kSymbolWidth, nil);
     
    		if (c=0) and (r = 0) then SetBelowItem(dialog1, kChosenSymbol, kFirstSymbol +c+kColumns*r,0,0);
    		if (c=0) and (r > 0) then SetBelowItem(dialog1, kFirstSymbol +c+kColumns*(r-1), kFirstSymbol +c+kColumns*r,0,-1);
    		if (c>0) then SetRightItem(dialog1, kFirstSymbol +c+kColumns*r-1, kFirstSymbol +c+kColumns*r,-1,0);
    		
    		end;
    		
    
    result := RunLayoutDialog(dialog1, Dialog_Handler);
     
    END;
    RUN(Example);

     

  7. I have tried also with the Image Control that responds to clicks but I did not get it to display the symbol image!

     

    I am doing this way:

    hImg := CreateImgFromSymbol('AM-530', 128,128, 0, 11, 9);
    if hImg <> nil then CreateImageControl(dialog1, 4, 200, 200, hImg);

    but, though the hImg is not nil, the symbol is not displayed. It is replaced by the Vectorworks icon.

     

    Below the code I am using to test.

    Of course, replace ''AM-530" with a symbol in your document.

     

    PROCEDURE Example;
    VAR
    dialog1 :INTEGER;
    int     :INTEGER;
    hImg : handle;
    
    PROCEDURE dialog1_Handler(VAR item :LONGINT; data :LONGINT);
    BEGIN
    
    CASE item OF
    	SetupDialogC:
    	BEGIN
    		SetItemClickable(dialog1, 4, TRUE);
    		EnableItem(dialog1, 4, TRUE);
    	END;
    		
    	4 : BEGIN
    			writeln('Strike!');
    		END;
    END;
    END;
    
    BEGIN
    writeln('Inizio');
    dialog1 := CreateLayout('Example', TRUE, 'OK', 'Cancel');
    
    {CreateSymbolDisplayControl(dialog1,  4,  'AM-530', 128, 128, 5, 0, 2);}
    hImg := CreateImgFromSymbol('AM-530', 128,128, 5, 0, 2);  
    if hImg <> nil then CreateImageControl(dialog1, 4, 200, 200, hImg);
    
    SetFirstLayoutItem(dialog1,  4);
    int := RunLayoutDialog(dialog1, dialog1_Handler);
    END;
    RUN(Example);

    Here's the results:

    838738230_Schermata2019-09-07alle16_10_53.thumb.png.7ca99592f4e4ea5055c6b2f3a5d2eeb7.png

    With the symbol control, the dialog is ok, but I cannot get clicks on the symbol…

     

    802949179_Schermata2019-09-07alle16_11_37.thumb.png.867fca6e3647aff2be48faafbcf16f5a.png

    With the image control, I get clicks fired, but not the correct image 🤔

     

  8. Thank you for the answer.

    Is the list browser you mention, the so called “tree control”?

    I need a pulldown menu that acts like the class pulldown menu, but I have to populate it with folder names contained in nested folders.

    Currently I have to keep all folders together to have “one level” only for these pulldown menu limitations, but I’d like to have subfolders (and submenus)...

  9. Hello,

    Is there a way to get a pulldown control in a VectorScript dialog that may have items with submenus, like the classes pulldown menu?

    I have explored functions the topic "Dialogs - Modern" of the VectorScript references, but did not find any clue.

    Yes, there is a tree control, but I have to remain in the size of a popup (more or less) for space needs.

     

    Any help?

    Thanks,

    Paolo

    Screenshot 2019-08-29 at 14.44.29.png

  10. Solved!

     

    Julian code needed only some retouch, the idea was right!

    The correct procedure (at least it works for my purposes) is as follows:

    …
    resultStatus := GetCustomObjectInfo(parmName, parmHand, parmRecordHand, wallHand);
    	
    	IF (resultStatus = TRUE) AND (parmHand <> NIL) AND (parmRecordHand <> NIL) THEN BEGIN
    	
    	if GetObject(PFILESCELTO) <> NIL then 
    	begin
    		symbol(PFILESCELTO, 0, 0, 0);
    		h1 := LNewObj;
    		h2 := GetCustomObjectProfileGroup(parmHand);
    		IF h2 <> Nil THEN DelObject(h2);
    		result := SetCustomObjectProfileGroup(parmHand, h1);
    	end;
    …

    In this way the symbol is not visible in the PIO representation, but is embedded and thus, copy / paste, of the object will include the symbol itself.

  11. Thank you,

    I have tried in the reset event (I am in an event driven plugin), but the symbol appears on the drawing…

     

    this is my code, PFILESCELTO is the symbol name, I have to check if it is on the drawing

    …
        parmName := 'BAD';
        parmHand := nil;
        parmRecordHand := nil;
        wallHand := nil;
        primoPassaggio := TRUE;
        
        resultStatus := GetCustomObjectInfo(parmName, parmHand, parmRecordHand, wallHand);
        
        IF (resultStatus = TRUE) AND (parmHand <> NIL) AND (parmRecordHand <> NIL) THEN BEGIN
        
        if GetObject(PFILESCELTO) <> NIL then 
        begin
            symbol(PFILESCELTO, 0, 0, 0);
            h1 := LNewObj;
            h2 := GetCustomObjectProfileGroup(parmHand);
            IF h2 <> Nil THEN DelObject(h2);
            IF h1 = NIL THEN result := SetCustomObjectProfileGroup(parmHand, h2);
        end;
    …

     

  12. Hello experts,
    I have developed a plugin object that takes advantage of a particular symbol to get from it the polyline it contains.
    If I copy / paste this object on another drawing, the symbol is not copied, because it is not actually drawn in the object, it is just used to get the polyline.
    Is there a way to embed the symbol inside the object without the need to draw it?

    Thank you for any help.

  13. Here's the script with the var passed as reference.

    It works only when you apply the trick

    s:=concat('', s);

    The result is a list of valid real numbers delimited by spaces, to be splitter later:

    35.938 135.145 36.233 140.511 36.971 140.511 36.971 135.145 145

     

    I'll try to port these in python. I do not know python, while I am an old Vectorscript developer.

    I hope python has a better array management (count, split etc.) as any modern language should.

    procedure trim;
    const
    testString = '<polygon  points="35.938,135.145 36.233,140.511     36.971,140.511 36.971,135.145     "/>';
    var
    r: dynarray[]of char;
    procedure trimNotInList(list: DYNARRAY[] OF CHAR; VAR s: dynarray[]of char);
    VAR
        i : INTEGER;
        t : dynarray[]of char;
    BEGIN
        t := s;
        i := 1;
        WHILE i <= Len(t) DO
            IF (Pos(Copy(t, i, 1), list) = 0) THEN
                Delete(t, i, 1)
            ELSE
                i := i + 1;
        s := t;
    END;
    procedure runOfSpacesIntoOne(var s:dynarray[]of char);
    var
    i:integer;
    temp: dynarray[] of char;
    begin
    s := Concat('',s); {pseudo reset}
    temp := '';
    for i:=1 to len(s) do
    begin
    temp:=concat(temp, s[i]);
    if (i>1) then
        if (s[i]=' ') and (s[i-1]=' ') then 
            temp := copy(temp, 1, len(temp)-1);
    end;
    s := temp;
    end;
    procedure trimSpaces(var s:dynarray[] of char);
    var
    i, ti, te:integer;
    begin
    s := Concat('',s); {pseudo reset}
        for i:=1 to len(s) do
        begin
            ti :=i;
            if s[i] <> ' ' then i := len(s); {esco dal for}
        end;
        for i:=len(s) downto 1 do
        begin
            te := i;
            if s[i] <> ' ' then i := 1; {esco dal for}
        end;
    s := copy(s, ti, te-ti+1);
    end;
    procedure replaceCommas(var s: dynarray[]of char);
    var
    i:integer;
    temp: string;
    begin
    s := Concat('',s); {pseudo reset}
    temp := '';
    for i:=1 to len(s) do
    begin
    if s[i] = ',' then temp:=Concat(temp,' ')
        else if s[i] = '-' then temp:=Concat(temp,' -')
        else temp:=Concat(temp,s[i])
    end;
    s := temp;
    end;
    {*********************** scanPolyPoints **********************}
    {return the substring between 'points="' and '"', I'll split these points later}
    procedure scanPolyPoints(parameter: string; line: DYNARRAY[] OF CHAR; var r:DYNARRAY[] OF CHAR);
    var
    index1, index2: integer;
    temp: DYNARRAY[] OF CHAR;
    begin
    index1 := Pos(parameter, line)+1+len(parameter);
    temp := copy(line, index1, len(line)-index1);
    index2 := Pos('"', temp);
    temp := copy(temp, 1, index2-1);
    temp := concat('', temp);
    trimNotInList('0123456789+-,. ',temp);
    replaceCommas(temp);
    runOfSpacesIntoOne(temp);
    r := temp; 
    trimSpaces(r);
    end;
    
    begin
    r:=teststring;
    scanPolyPoints(' points=', teststring, r);
    writeln(r);
    end;
    run(trim);

     

  14. I am trying to develop an SVG reader in Vectorscript, but I am at a stake because of the impossibility to manage functions or procedures that calculate and return strings that may have more than 255 chars.
    Having to do with SVG commands like this…

    <path fill="none" stroke="#000000" stroke-width="0.238" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-dasharray="1,1" d="
        M47.506,645.356c0.099,0,0.197-0.049,0.296-0.049c0.098,0,0.196-0.05,0.295-0.099s0.197-0.049,0.296-0.099
        c0.098-0.049,0.196-0.099,0.246-0.147c0.098-0.049,0.196-0.099,0.246-0.147c0.098-0.05,0.147-0.099,0.246-0.148
        c0.099-0.049,0.147-0.147,0.246-0.196c0.049-0.05,0.147-0.148,0.196-0.197c0.05-0.049,0.148-0.147,0.197-0.246
        s0.099-0.147,0.197-0.246c0.049-0.099,0.098-0.147,0.147-0.246c0.049-0.099,0.099-0.197,0.147-0.295
        c0.05-0.148,0.147-0.296,0.197-0.493c0.049-0.147,0.099-0.295,0.196-0.492c0.05-0.147,0.099-0.345,0.148-0.492
        c0.049-0.196,0.147-0.442,0.196-0.64c0-0.05,0.05-0.147,0.05-0.197c0-0.049,0.049-0.147,0.049-0.197
        c0-0.049,0.05-0.147,0.05-0.196c0-0.05,0.049-0.147,0.049-0.197c0-0.049,0-0.049,0-0.099c0-0.049,0-0.049,0-0.098
        c0-0.05,0-0.05,0-0.099c0-0.05,0-0.05-0.049-0.099c0-0.049-0.05-0.049-0.05-0.049l-0.049-0.05l-0.05-0.049
        c-0.049,0-0.049-0.05-0.099-0.05c-0.049,0-0.049,0-0.098,0c-0.05,0-0.05,0-0.099,0c-0.05,0-0.05,0-0.099,0s-0.049,0-0.099,0.05
        c-0.049,0-0.049,0.049-0.099,0.049l-0.049,0.05l-0.049,0.049c0,0-0.05,0.049-0.05,0.099c0,0.049-0.049,0.099-0.049,0.147
        s-0.05,0.099-0.05,0.147c0,0.05-0.049,0.099-0.049,0.148c0,0.049-0.049,0.098-0.049,0.147c-0.05,0.099-0.099,0.246-0.197,0.345
        c-0.05,0.099-0.099,0.246-0.197,0.345c-0.099,0.147-0.147,0.246-0.246,0.394s-0.147,0.246-0.246,0.394s-0.197,0.246-0.246,0.345
        s-0.147,0.147-0.197,0.246c-0.049,0.099-0.147,0.147-0.196,0.197c-0.05,0.049-0.147,0.147-0.197,0.196
        c-0.049,0.05-0.147,0.148-0.246,0.197s-0.147,0.099-0.246,0.147c-0.099,0.05-0.147,0.099-0.246,0.148
        c-0.099,0.049-0.197,0.098-0.246,0.147c-0.099,0.049-0.197,0.099-0.296,0.147c-0.147,0.049-0.295,0.099-0.442,0.147
        c-0.147,0.05-0.296,0.099-0.443,0.148c-0.147,0.049-0.295,0.098-0.443,0.147c-0.098,0.049-0.196,0.049-0.295,0.099
        c-0.099,0-0.197,0.049-0.296,0.049c-0.049,0-0.147,0.049-0.196,0.049c-0.05,0-0.147,0-0.197,0.05c-0.049,0-0.147,0-0.196,0.049
        c-0.05,0-0.148,0-0.197,0.05c-0.05,0-0.05,0-0.099,0s-0.049,0-0.099,0.049c-0.049,0-0.049,0.049-0.049,0.049l-0.05,0.05
        l-0.049,0.049c0,0.05-0.049,0.05-0.049,0.099s0,0.049,0,0.099c0,0.049,0,0.049,0,0.099c0,0.049,0,0.049,0,0.098
        c0,0.05,0,0.05,0.049,0.099c0,0.05,0.049,0.05,0.049,0.099l0.05,0.049l0.049,0.05c0,0,0.05,0.049,0.099,0.049s0.049,0,0.099,0.05
        c0.049,0,0.049,0,0.099,0c0.049,0,0.099,0,0.147,0s0.099,0,0.147,0c0.05,0,0.099,0,0.147,0c0.05,0,0.099,0,0.148,0
        c0.147,0,0.295,0,0.442,0c0.148,0,0.296,0,0.443,0s0.345,0,0.492-0.05c0.147,0,0.345-0.049,0.492-0.049
        C47.161,645.406,47.359,645.406,47.506,645.356z”/>

    … that goes very beyond the 255 chars strings limit, I had necessarily to substitute functions returning strings into functions returning dynarray[]of char, but this is FORBIDDEN.
    So I tried with procedures returning dynarray[]of char as VAR (this is allowed) but I found strange behaviors.

     

    For example, the following script takes the constant string (this is a short string, just for instance).
    The first procedure extracts the substring starting from 'points="' and the subsequent '"'.
    The second procedure replaces the commas with spaces.
    Both procedure uses the same VAR s:string declared.

    procedure test;
    const
    polygon = '<polygon  points="35.938,135.145 36.233,140.511     36.971,140.511 36.971,135.145     "/>’; 
    {this is just an example of SVG line, this is < 256 chars, but this is a special case}
        
    var
    s: dynarray[]of char; {declare the VAR I'll use later as value returned from procedures}
        
    {*********************** scanPolyPoints **********************}
    {return the substring between 'points="' and '"', I'll split these points later}
    procedure scanPolyPoints(parameter: string; line: DYNARRAY[] OF CHAR; var r:DYNARRAY[] OF CHAR);
    var
    index1, index2: integer;
    temp: DYNARRAY[] OF CHAR;
    begin
    {search the position of 'parameter='}
    index1 := Pos(parameter, line)+1+len(parameter);
    temp := copy(line, index1, len(line)-index1); {remaining string} 
    {search the position of '"' in the remaining string}
    index2 := Pos('"', temp);
    temp := copy(temp, 1, index2-1); {here I have only the string composed by points} 
    r := temp; {set the answer r}
    end;
    
    {*********************** replaceCommas **********************}
    {substitute each comma with a space and each minus signs with ' -'}
    {in the SVG (generated by Adobe Illustrator), the path numbers are separated by a ',' or by '-' or by a space}
    {whenever you find a '-', the ',' is omitted!}
    procedure replaceCommas(source:dynarray[]of char; var dest: dynarray[]of char);
    var
    i:integer;
    temp: string;
    begin
    temp := '';
    for i:=1 to len(source) do
    begin
    if source[i] = ',' then temp:=Concat(temp,' ')
        else if source[i] = '-' then temp:=Concat(temp,' -')
        else temp:=Concat(temp,source[i])
    end;
    dest := temp;
    end;
    begin
    s := ''; {init}
    writeln(polygon); {write the input string to the standard output}
    scanPolyPoints(' points=', polygon, s); {first procedure}
    writeln(s); {write the resulting "s" string to the standard output}
    {Now I use the variable s both as parameter and resulting var}
    replaceCommas(s, s); {second procedure, commas should be replaced by spaces}
    writeln(s); {but NO! It's unchanged}
    {test it with a constant string as parameter…}
    replaceCommas('.,.,.,.,.,.,.,', s);
    writeln(s); {…it works!}
    end;
    run(test);    

    The resulting output is the following:

    <polygon  points="35.938,135.145 36.233,140.511             36.971,140.511 36.971,135.145         "/>
    35.938,135.145 36.233,140.511             36.971,140.511 36.971,135.145         
    35.938,135.145 36.233,140.511             36.971,140.511 36.971,135.145         
    . . . . . . . 

    As you can see, the first procedure works (line 2), the second no (line 3 has still commas in place!). While the constant string has the commas removed (line 4).

    Where is the problem and, most of all, is there a solution?

     

    Thank you for any help.

    Paolo Marcuccetti

     


     

×
×
  • Create New...