CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Drukowanie tekstu na różnych drukarkach

Drukowanie tekstu na różnych drukarkach

dział ogólny

Drukowanie tekstu na różnych drukarkach

Nowy postprzez duf » poniedziałek, 29 sierpnia 2011, 09:27

Jak wydrukować tekst w kreślonym miejscu na A4 używając różnych drukarek? W moim przypadku na jednej OKI tekst
KOD cpp:     UKRYJ  
Printer()->Canvas->TextOut( 100, 200, "Przykładowy tekst.");
jest w innym miejscu niż na innej drukarce. Skąd wiedzieć jakie wartości współrzędnych ustawić dla konkretnej drukarce?
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie tekstu na różnych drukarkach

Nowy postprzez Cyfrowy Baron » poniedziałek, 29 sierpnia 2011, 18:08

Trzeba ustawić zmienną która będzie przechowywała współczynnik określający np. szerokość strony do jej rozdzielczości. Podając pozycję strony trzeba mnożyć wartości przez ten współczynnik.

Jeżeli np. w rozdzielczości 300dpi strona ma długość 2400, to współczynnik będzie wyglądał tak: ratio = Printer()->PageWidth / 2400 = 1; gdyż przy 300dpi PageWidth jest równe 2400, ale już przy 600dpi PageWidth = 4800, więc ratio = Printer()->PageWidth / 1200 = 2.
Mnożąc pozycję przez współczynnik tekst zawsze będzie znajdował się w określonej przez Ciebie pozycji.
Współczynnik należy obliczać po wywołaniu metody BeginDoc(), gdyż przed wywołaniem tej metody Printer() nie zna wymiarów drukowanej strony:

KOD cpp:     UKRYJ  
 Printer()->BeginDoc();

 int pw = Printer()->PageWidth;  // długość strony.

 int ph = Printer()->PageHeight; // wysokość strony.

 double ratio_x = pw / 2400;
 double ratio_y = ph / 3344;

 Printer()->Canvas->TextOut(100 *  ratio_x, 200 * ratio_y, "Przykładowy tekst.");

 Printer()->EndDoc();


Ustalasz współczynnik dla jednej rozdzielczości i ustalasz pozycję tekstu na stronie w oparciu o tą rozdzielczość. Na różnych drukarkach rozdzielczość dpi zawsze będzie taka sama, ale rozmiar strony może się różnić w zależności od tego jakie marginesy obsługuje drukarka. Ja np. testowałem ten kod na drukarce przy rozdzielczości 300dpi i otrzymałem dla PageWidt dwa różne wyniki 2400 i 2480 a to dlatego, że druga drukarka miała mniejsze marginesy, dlatego pozycja tekstu: 100 * ratio_x da na dwóch drukarkach różne wyniki: 100 * 1 = 100; 100 * 1.03 = 103; W drugim przypadku tekst zostanie przesunięty o trzy piksele bardziej w prawą stronę, ale ponieważ wymiar strony jest trochę większy to licząc w milimetrach w obydwu przypadkach tekst będzie mniej więcej w tej samej pozycji.

By uniknąć tej zabawy z marginesami lepiej jest pobierać całkowity fizyczny rozmiar obszaru drukowania i w oparciu o niego obliczać współczynnik. Dla rozdzielczości 300dpi wynosi on 2480:


KOD cpp:     UKRYJ  
 Printer()->BeginDoc();

 TPoint PhysPageSize;

 Escape( Printer()->Handle, GETPHYSPAGESIZE, 0, NULL, &PhysPageSize);

 double ratio = PhysPageSize.x / 2480;

 Printer()->Canvas->TextOut(100 *  ratio, 200 * ratio, "Przykładowy tekst.");

 Printer()->EndDoc();

Tym razem w przykładzie użyłem jednego współczynnika do obliczania pozycji tekstu w poziomie i w pionie, gdyż jeden w zupełności wystarczy.

Można też pobrać rozdzielczość drukarki i w oparciu o nią obliczać współczynnik, ale to się do niczego nie przyda, gdyż nie uwzględnia to marginesów. Niemniej jednak rozdzielczość drukarki można sprawdzić tak:

KOD cpp:     UKRYJ  
 Printer()->BeginDoc();
 int resolution = GetDeviceCaps(Printer()->Handle, LOGPIXELSX);

 Printer()->EndDoc();


Gdybyś chciał wyliczyć marginesy drukarki to sprawa jest prosta:

KOD cpp:     UKRYJ  
 /* rozdzielczość w poziomie i w pionie, w praktyce identyczne */
 int ppi_x = GetDeviceCaps(Printer()->Handle, LOGPIXELSX);
 int ppi_y = GetDeviceCaps(Printer()->Handle, LOGPIXELSY);

 int pr_x = GetDeviceCaps(Printer()->Handle, HORZRES); /* to samo co Printer()->PageWidth */
 int pr_y = GetDeviceCaps(Printer()->Handle, VERTRES); /* to samo co Printer()->PageHeight */

 TPoint PhysPageSize;
 /* całkowity rozmiar strony razem z marginesami */
 Escape( Printer()->Handle, GETPHYSPAGESIZE, 0, NULL, &PhysPageSize);

 TPoint Offset;
 /* marginesy lewy raz górny */
 Escape( Printer()->Handle, GETPRINTINGOFFSET, 0, NULL, &Offset);


 int margin_Left   = Offset.x;
 int margin_Top    = Offset.y;

 int margin_Right  = PhysPageSize.x - pr_x - Offset.x;
 int margin_Bottom = PhysPageSize.y - pr_y - Offset.y;

 /* obliczamy rozmiar strony w milimetrach */
 int page_width_mm  = (PhysPageSize.x / ppi_x) * 25.4;
 int page_height_mm = (PhysPageSize.y / ppi_y) * 25.4;

  /* obliczamy rozmiar strony w centymetrach */
 int page_width_cm  = (PhysPageSize.x / ppi_x) * 2.54;
 int page_height_cm = (PhysPageSize.y / ppi_y) * 2.54;

 /* obliczamy marginesy w centymetrach */
 int margin_Left_cm   = (margin_Left   / ppi_x)  * 2.54;
 int margin_Top_cm    = (margin_Top    / ppi_y)  * 2.54;
 int margin_Right_cm  = (margin_Right  / ppi_x)  * 2.54;
 int margin_Bottom_cm = (margin_Bottom / ppi_y)  * 2.54;


Funkcje GetDeviceCaps i Escape sprawdzają parametry drukarki bez konieczności jej uruchamiania za pomocą funkcji BeginDoc.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
duf
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie tekstu na różnych drukarkach

Nowy postprzez duf » poniedziałek, 29 sierpnia 2011, 21:50

Cyfrowy Baron napisał(a):
KOD cpp:     UKRYJ  
 Printer()->BeginDoc();

 int pw = Printer()->PageWidth;  // długość strony.

 int ph = Printer()->PageHeight; // wysokość strony.

 double ratio_x = pw / 2400;
 double ratio_y = ph / 3344;

 Printer()->Canvas->TextOut(100 *  ratio_x, 200 * ratio_y, "Przykładowy tekst.");

 Printer()->EndDoc();



Dziękuję za obszerną odpowiedź. Jak jest różnica pomiędzy długością a wysokością strony? A co z szerokością? Dlaczego przy rozdzielczości 600 dpi dzielimy przez 1200 czyli połowę PageWidth. Czy przy rozdzielczości 1200 dpi dzieliłbyś przez 600 ap przy 150 dpi przez 4800 ? Czy 300 dpi to jakaś wyjściowa wartość?
Żeby tekst był w tym samym miejscu pomiędzy drukarką OKI ( PageWidth 960, PhyPageSize 992, 120 dpi ) a Canon( PageWidth 4720, PhyPageSize 4960, 600 dpi ) to dzielić muszę przez 7:
Kod: Zaznacz cały
TPoint PhysPageSize;
  Escape( Printer()->Handle, GETPHYSPAGESIZE, 0, NULL, &PhysPageSize );

  int resolution = GetDeviceCaps( Printer()->Handle, LOGPIXELSX );
  double ratio_x, ratio_y, pw, ph, w = 0;

  pw = Printer()->PageWidth;
  ph = Printer()->PageHeight;

  if ( resolution <= 300 )
  {
   ratio_x = pw / PhysPageSize.x;
   ratio_y = ph / PhysPageSize.y;
  }
  else if ( resolution == 600 ) {

   ratio_x = pw / (PhysPageSize.x/7.0);
   ratio_y = ph / (PhysPageSize.y/7.0);
  }
  Printer()->BeginDoc();
  Printer()->Canvas->TextOut(100 *  ratio_x, 200 * ratio_y, "Przykładowy tekst.");
  Printer()->EndDoc();
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie tekstu na różnych drukarkach

Nowy postprzez Cyfrowy Baron » wtorek, 30 sierpnia 2011, 15:23

duf napisał(a):Dziękuję za obszerną odpowiedź. Jak jest różnica pomiędzy długością a wysokością strony? A co z szerokością?


Długość i szerokość to dla mnie to sam0.

duf napisał(a):Dlaczego przy rozdzielczości 600 dpi dzielimy przez 1200 czyli połowę PageWidth.


Nie dzielimy przez 1200. Ustalamy jedną rozdzielczość np. 300 dpi i stosujemy jeden współczynnik. Przy rozdzielczości 300 dpi Width = 2400, a przy rozdzielczości 600 dpi Width równa się 4800, gdy więc dzielisz 2400 / 2400 to współczynnik wynosi 1, ale gdy dzielisz 4800 / 2400 to współczynnik wynosi 2.

duf napisał(a):Czy 300 dpi to jakaś wyjściowa wartość?


Sam sobie ustalasz dla jakiej rozdzielczości programujesz kod. Jeżeli użyjesz za punkt wyjścia 600 dpi i będziesz ustalał współczynnik dzieląc przez 4800 to wynik drukowania i tak będzie ten sam, gdy przy drukowaniu w 300 dpi będziesz miał Width = 2400 / 4800 = 0,5.
Najwyraźniej nie rozumiesz czym jest płótno TCanvas. Zwiększając rozdzielczość nie zwiększasz obszaru drukowania, lecz zwiększasz liczbę punktów na tym obszarze. Gdy zwiększasz np. rozdzielczość ekranu, np. z 1024x768 na 1280x1024 to przecież monitor nie zmienia rozmiaru, pozycja ikon względem siebie jak też względem lewego górnego rogu ekranu też się nie zmieni.

duf napisał(a):Żeby tekst był w tym samym miejscu pomiędzy drukarką OKI ( PageWidth 960, PhyPageSize 992, 120 dpi ) a Canon( PageWidth 4720, PhyPageSize 4960, 600 dpi ) to dzielić muszę przez 7:


NIE! :twisted: Ustalasz jeden współczynnik dla jednej rozdzielczości. Drukarka sama sobie wszystko przeliczy. NIezleżenie od tego na jakiej drukarce drukujesz ten kod:

KOD cpp:     UKRYJ  
Printer()->BeginDoc();

 TPoint PhysPageSize;

 Escape( Printer()->Handle, GETPHYSPAGESIZE, 0, NULL, &PhysPageSize);

 double ratio = PhysPageSize.x / 2480;

 Printer()->Canvas->TextOut(100 *  ratio, 200 * ratio, "Przykładowy tekst.");

 Printer()->EndDoc();


Da identyczny efekt końcowy niezależnie od tego w jakiej rozdzielczości i na jakiej drukarce będziesz drukował, o ile obydwie drukarki pracują w tym samym standardzie.

Twój kod powinien wyglądać tak:

KOD cpp:     UKRYJ  
 TPoint PhysPageSize;

 Escape( Printer()->Handle, GETPHYSPAGESIZE, 0, NULL, &PhysPageSize );

 double ratio = PhysPageSize.x / 2480;

 Printer()->BeginDoc();

 Printer()->Canvas->TextOut(100 *  ratio; 200 * ratio, "Przykładowy tekst.");

 Printer()->EndDoc();
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie tekstu na różnych drukarkach

Nowy postprzez duf » czwartek, 1 września 2011, 10:38

Zgadza się to wszystko o czym piszesz co do drukarek HP lub Canon drukarek laserowych ale na igłówce OKI nie mam oczekiwanego przeskalowania.
A przy okazji czy z poziomu kodu można rozkazać drukarce igłowej żeby wróciła papier do początku strony po zakończonym drukowaniu, bo zazwyczaj przewija papier do końca strony?
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie tekstu na różnych drukarkach

Nowy postprzez Cyfrowy Baron » czwartek, 1 września 2011, 15:46

Drukarki igłowe pracują w innym standardzie. Nie mam żadnego doświadczenia ani nawet dostępu do takiej drukarki.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 10 gości

cron