Pixels Per Inch (Final Leg Of Shading)

Pixels Per Inch (Final Leg Of Shading)

Post by Lee Peedi » Wed, 09 Jul 2003 23:32:54



OK,
Thanks to the great help here I've got my ActiveX DLL printing
polygons.
Mike suggested a method to convert my coordinates (which are in
inches) to pixels and I'm sure it was a valid solution - I'm just not
up enough on VB to follow all of it :-).
After a bit of stumbling around I think I may have a solution - please
comment.

Using the GetDeviceCaps API I can easily determine the "Twips Per
Pixel" for both the X & Y axis.

Since there are 1440 twips per inch (I believe that to be a constant),
I can then easily convert my inches to pixels.

X1 = .665 Inches
TPI = 1440  'Twips per inch

total_twips = X1 * TPI   '957.6

TPPX = 15 'Twips Per Pixel of Current Printer'

Pixels = total_twips / TPPX  '63.84

So with the current printer .665 Inches resolves to 63.84 Pixels

Does anyone see anything wrong with this solution?

Thanks again for everyone's help.
Lee

 
 
 

Pixels Per Inch (Final Leg Of Shading)

Post by Larry Serflate » Thu, 10 Jul 2003 00:34:48



Quote:

> Using the GetDeviceCaps API I can easily determine the "Twips Per
> Pixel" for both the X & Y axis.

Why not just use the Printer.TwipsPerPixelX (and Y)  values?

Quote:> TPPX = 15 'Twips Per Pixel of Current Printer'

Are you sure that is for your printer???  That looks a bit high!
In fact it looks like it is for your screen.

Compare it to Printer.TwipsPerPixelX....

LFS

 
 
 

Pixels Per Inch (Final Leg Of Shading)

Post by Lee Peedi » Thu, 10 Jul 2003 01:07:43


On Tue, 8 Jul 2003 10:34:48 -0500, "Larry Serflaten"



>> Using the GetDeviceCaps API I can easily determine the "Twips Per
>> Pixel" for both the X & Y axis.

>Why not just use the Printer.TwipsPerPixelX (and Y)  values?

As part of my PrinterObject ActiveX dll, I was already creating an
array of other information about the printer such as the border areas
that were not printable.  I simply added two more elements to the
array that were exactly as you suggested.

Quote:>> TPPX = 15 'Twips Per Pixel of Current Printer'

>Are you sure that is for your printer???  That looks a bit high!
>In fact it looks like it is for your screen.

>Compare it to Printer.TwipsPerPixelX....

You are correct - At the time I ran my tests I had my printer set to a
nice little "printer" called Margi Presenter-To-Go.  This allows
anything in Windows that can be printed to be sent to a Palm PDA.
Quite conveniently, it has a "view" feature, so I use it as as "print
preview".

Other "real" printers return values ranging from 2 to 8 (sound more
reasonable?).

Lee

Quote:>LFS

 
 
 

Pixels Per Inch (Final Leg Of Shading)

Post by Larry Serflate » Thu, 10 Jul 2003 01:39:54



Quote:> Other "real" printers return values ranging from 2 to 8 (sound more
> reasonable?).

Yes that is more in line with current printers....

<g>
LFS

 
 
 

Pixels Per Inch (Final Leg Of Shading)

Post by Mike D Sutto » Thu, 10 Jul 2003 21:23:52


Hi Lee,
    Apologies for the late reply, I was working on-site yesterday and had no
newsgroup access.

Quote:> Thanks to the great help here I've got my ActiveX DLL printing
> polygons.
> Mike suggested a method to convert my coordinates (which are in
> inches) to pixels and I'm sure it was a valid solution - I'm just not
> up enough on VB to follow all of it :-).
> After a bit of stumbling around I think I may have a solution - please
> comment.

> Using the GetDeviceCaps API I can easily determine the "Twips Per
> Pixel" for both the X & Y axis.

> Since there are 1440 twips per inch (I believe that to be a constant),
> I can then easily convert my inches to pixels.

<snip>

My previous post on mapping modes was really just to show you haw you go
about calling the API calls rather than an exact solution (That part's your
job! ;)
Since you're working with floating point values then you're going to have to
do some of the re-mapping yourself since these would be rounded by the API
(All integer based) and everything would be aligned to the nearest inch!
The API has two mapping modes defined which take pixel (device) coordinates
and map them to inch-based mapping modes, the first is MM_LOENGLISH which
would require you to multiply each coordinate by 100 (To maintain some of he
data from the floating point value.)  If you need more precision then
MM_HIENGLISH gives you 10* the resolution and would require you to multiple
each coordinate by 1000 thus taking into account more of the original value.
For more precision still then you can always create your own isometric
mapping mode (As described in the previous post) and set that onto the
printer's DC before drawing.
If you have control over the original point data then IMO this would be the
preferred solution since you need never worry about accidentally forgetting
to re-map something and it will reduce the clutter in your own code.
If you're receiving these values from an external source though or for some
other reason can't/don't want to change the coordinates then you'll need to
go on the way you've got currently with manual mapping.
Of course, if you're using VB's drawing methods rather than GDI drawing
methods then you can just set the ScaleMode of the printer object and your
floating point coordinates will work as-is.
Hope this helps,

    Mike

 - Microsoft Visual Basic MVP -

WWW: Http://www.mvps.org/EDais/

 
 
 

Pixels Per Inch (Final Leg Of Shading)

Post by Lee Peedi » Fri, 11 Jul 2003 02:46:26


Thanks again for your input.  I don't think (unless I'm really missing
something) that I'll have a problem with the floating point being
converted to integers.  I will do all the math to convert to pixels in
my script code.  The primary reason for this is that each set of
coordinates may have their own "scale" (ie 1"=100').  If I understand
what you're saying, the worst is that a coordinate will be rounded to
the nearest "pixel" not "inch".  Quite frankly, I don't think I could
discern the difference on a printout of a half pixel.

I seem to be having a bit of a problem with sending data from my
scripting language (Object Rexx) to a "parameter array" as Larry
suggested.

If I send the data like Larry suggested -
  MyDll.Shade X1,Y1, X2,Y2, X3, Y3
or in Object Rexx
  MyDll~Shade(x1,y1,x2,y2,x3,y3)
all is well and everything works fine.

However if I attempt to make the list of parameters a variable as in..
params = "x1,y1,x2,y2,x3,y3"
MyDll~Shade(params)
the dll does appear to recognize the data.  This method of passing
parameters from Object Rexx to other VB ActiveX dll's works OK when I
know exactly how many parameters there should be and account for them
in the DLL.

OR

xyarray = .array~new
xyarray[1] = x1
xyarray[2] = y1
etc.
MyDll~Shade(xyarray)

I get a type mis-match.  There are several other types of Object Rexx
"collections" that I haven't had an opportunity to test yet.  I know I
can pass a VB array from an ActiveX dll back to a calling Object Rexx
script and Obj Rexx will recognize it as an array.
I guess there's just something "special" about a "parameter array"
:-(.

I may have to set this "learning project" aside for a short while -
got a big "paying" job coming up; however, I will continue to work
with it as time progresses.

I'll probably send what I have so far directly to the IBM Object Rexx
project team.  I just happen to be on a "first name" basis with them
and in the past they have readily "enchanced" Object Rexx to work with
other languages in regards to ActiveX/OLE.  Maybe they'll add a new
collection type called "A_Lee_Collection" :-).

Thanks again for all your help.
Lee

On Wed, 9 Jul 2003 13:23:52 +0100, "Mike D Sutton"


>Hi Lee,
>    Apologies for the late reply, I was working on-site yesterday and had no
>newsgroup access.

>> Thanks to the great help here I've got my ActiveX DLL printing
>> polygons.
>> Mike suggested a method to convert my coordinates (which are in
>> inches) to pixels and I'm sure it was a valid solution - I'm just not
>> up enough on VB to follow all of it :-).
>> After a bit of stumbling around I think I may have a solution - please
>> comment.

>> Using the GetDeviceCaps API I can easily determine the "Twips Per
>> Pixel" for both the X & Y axis.

>> Since there are 1440 twips per inch (I believe that to be a constant),
>> I can then easily convert my inches to pixels.
><snip>

>My previous post on mapping modes was really just to show you haw you go
>about calling the API calls rather than an exact solution (That part's your
>job! ;)
>Since you're working with floating point values then you're going to have to
>do some of the re-mapping yourself since these would be rounded by the API
>(All integer based) and everything would be aligned to the nearest inch!
>The API has two mapping modes defined which take pixel (device) coordinates
>and map them to inch-based mapping modes, the first is MM_LOENGLISH which
>would require you to multiply each coordinate by 100 (To maintain some of he
>data from the floating point value.)  If you need more precision then
>MM_HIENGLISH gives you 10* the resolution and would require you to multiple
>each coordinate by 1000 thus taking into account more of the original value.
>For more precision still then you can always create your own isometric
>mapping mode (As described in the previous post) and set that onto the
>printer's DC before drawing.
>If you have control over the original point data then IMO this would be the
>preferred solution since you need never worry about accidentally forgetting
>to re-map something and it will reduce the clutter in your own code.
>If you're receiving these values from an external source though or for some
>other reason can't/don't want to change the coordinates then you'll need to
>go on the way you've got currently with manual mapping.
>Of course, if you're using VB's drawing methods rather than GDI drawing
>methods then you can just set the ScaleMode of the printer object and your
>floating point coordinates will work as-is.
>Hope this helps,

>    Mike

> - Microsoft Visual Basic MVP -

>WWW: Http://www.mvps.org/EDais/

 
 
 

Pixels Per Inch (Final Leg Of Shading)

Post by Larry Serflate » Fri, 11 Jul 2003 03:20:01



Quote:> I get a type mis-match.  There are several other types of Object Rexx
> "collections" that I haven't had an opportunity to test yet.  I know I
> can pass a VB array from an ActiveX dll back to a calling Object Rexx
> script and Obj Rexx will recognize it as an array.
> I guess there's just something "special" about a "parameter array"
> :-(.

Yeah, basically there is something special about it, but its pretty handy
when you can use it.

Put another way a ParamArray declaration might look like this:

Public Sub MySub(Optional ByRef A(0) As Variant [, Optional ByRef A(n) As Variant])

When A(n) is determined by the calling procedure.

What about a delimited string?  The main point I was making was that
it could be written to allow the caller to determine how many pairs to
send, and the routine could determine for itself, how many there were,
rahter than make the caller provide that value.  How you do it is up
to you, whatever works!  ;-)

LFS

> I may have to set this "learning project" aside for a short while -
> got a big "paying" job coming up; however, I will continue to work
> with it as time progresses.

> I'll probably send what I have so far directly to the IBM Object Rexx
> project team.  I just happen to be on a "first name" basis with them
> and in the past they have readily "enchanced" Object Rexx to work with
> other languages in regards to ActiveX/OLE.  Maybe they'll add a new
> collection type called "A_Lee_Collection" :-).

> Thanks again for all your help.
> Lee

> On Wed, 9 Jul 2003 13:23:52 +0100, "Mike D Sutton"

> >Hi Lee,
> >    Apologies for the late reply, I was working on-site yesterday and had no
> >newsgroup access.

> >> Thanks to the great help here I've got my ActiveX DLL printing
> >> polygons.
> >> Mike suggested a method to convert my coordinates (which are in
> >> inches) to pixels and I'm sure it was a valid solution - I'm just not
> >> up enough on VB to follow all of it :-).
> >> After a bit of stumbling around I think I may have a solution - please
> >> comment.

> >> Using the GetDeviceCaps API I can easily determine the "Twips Per
> >> Pixel" for both the X & Y axis.

> >> Since there are 1440 twips per inch (I believe that to be a constant),
> >> I can then easily convert my inches to pixels.
> ><snip>

> >My previous post on mapping modes was really just to show you haw you go
> >about calling the API calls rather than an exact solution (That part's your
> >job! ;)
> >Since you're working with floating point values then you're going to have to
> >do some of the re-mapping yourself since these would be rounded by the API
> >(All integer based) and everything would be aligned to the nearest inch!
> >The API has two mapping modes defined which take pixel (device) coordinates
> >and map them to inch-based mapping modes, the first is MM_LOENGLISH which
> >would require you to multiply each coordinate by 100 (To maintain some of he
> >data from the floating point value.)  If you need more precision then
> >MM_HIENGLISH gives you 10* the resolution and would require you to multiple
> >each coordinate by 1000 thus taking into account more of the original value.
> >For more precision still then you can always create your own isometric
> >mapping mode (As described in the previous post) and set that onto the
> >printer's DC before drawing.
> >If you have control over the original point data then IMO this would be the
> >preferred solution since you need never worry about accidentally forgetting
> >to re-map something and it will reduce the clutter in your own code.
> >If you're receiving these values from an external source though or for some
> >other reason can't/don't want to change the coordinates then you'll need to
> >go on the way you've got currently with manual mapping.
> >Of course, if you're using VB's drawing methods rather than GDI drawing
> >methods then you can just set the ScaleMode of the printer object and your
> >floating point coordinates will work as-is.
> >Hope this helps,

> >    Mike

> > - Microsoft Visual Basic MVP -

> >WWW: Http://www.mvps.org/EDais/

 
 
 

Pixels Per Inch (Final Leg Of Shading)

Post by Lee Peedi » Fri, 11 Jul 2003 04:08:44


Well I didn't want to expose all my VB ignorance :-), but I was sure
hoping that someone could suggest a "delimeted string".  
Now the "$64K" question - given that I pass to the DLL function the
number of elements in the string and a comma delimeted string. How do
I turn that into a VB Array?  (I know, I'm really showing my ignorance
now).

MyDLL~Shade(num_elements,element_string)

Public Function Shade(n_e as Variant, e_s as Variant)
'need code here to turn e_s (comma delimeted) into the array "points".

    Dim Pts() As PointAPI
    Dim DrawBrush As Long
    Dim OldBrush As Long, OldPen As Long
    Dim ub As Long, i As Long
    ub = UBound(points)
...
...
...

On Wed, 9 Jul 2003 13:20:01 -0500, "Larry Serflaten"



>> I get a type mis-match.  There are several other types of Object Rexx
>> "collections" that I haven't had an opportunity to test yet.  I know I
>> can pass a VB array from an ActiveX dll back to a calling Object Rexx
>> script and Obj Rexx will recognize it as an array.
>> I guess there's just something "special" about a "parameter array"
>> :-(.

>Yeah, basically there is something special about it, but its pretty handy
>when you can use it.

>Put another way a ParamArray declaration might look like this:

>Public Sub MySub(Optional ByRef A(0) As Variant [, Optional ByRef A(n) As Variant])

>When A(n) is determined by the calling procedure.

>What about a delimited string?  The main point I was making was that
>it could be written to allow the caller to determine how many pairs to
>send, and the routine could determine for itself, how many there were,
>rahter than make the caller provide that value.  How you do it is up
>to you, whatever works!  ;-)

>LFS

 
 
 

Pixels Per Inch (Final Leg Of Shading)

Post by Mike D Sutto » Fri, 11 Jul 2003 06:03:23


Quote:> Well I didn't want to expose all my VB ignorance :-), but I was sure
> hoping that someone could suggest a "delimeted string".
> Now the "$64K" question - given that I pass to the DLL function the
> number of elements in the string and a comma delimeted string. How do
> I turn that into a VB Array?  (I know, I'm really showing my ignorance
> now).

<snip>

Split() will take your comma delimited string and turn it into an array of
strings, then perform a CLng() on each of those to convert to an array of
longs, you needn't pass the number of elements as it's simply the Comma
count + 1, or if you're working with 2D points then (Comma count \ 2) + 1 --
Notice; integer divide rather than floating point divide.

'*** (Air code...)
Dim Coords() As String
Dim NumCoords As Long, LoopCoords As Long
Dim IntCoords() As PointAPI

' Break the delimited string into an array of strings
Coords() = Split(inCoords, ",")
NumCoords = UBound(Coords())

' Make sure there's enough values to establish some points
If (NumCoords < 1) Then Exit Sub

' Declare a data array of 2D points
ReDim IntCoords(NumCoords \ 2) As Long

' Iterate the data array and convert to numerics
For LoopCoords = 0 To (NumCoords And (Not &H1)) Step 2
    With IntCoords(LoopCoords \ 2)
        .X = CLng(Coords(LoopCoords))
        .Y = CLng(Coords(LoopCoords + 1))
    End With
Next LoopCoords
'***

Hope this helps,

    Mike

 - Microsoft Visual Basic MVP -

WWW: Http://www.mvps.org/EDais/