Bagikan melalui


Menggambar Teks dari Font Berbeda pada Baris yang Sama

Gaya jenis yang berbeda dalam keluarga font dapat memiliki lebar yang berbeda. Misalnya, gaya keluarga yang tebal dan miring selalu lebih lebar dari gaya romawi untuk ukuran titik tertentu. Saat Anda menampilkan atau mencetak beberapa gaya tipe pada satu baris, Anda harus melacak lebar garis untuk menghindari karakter ditampilkan atau dicetak di atas satu sama lain.

Anda dapat menggunakan dua fungsi untuk mengambil lebar (atau jangkauan) teks dalam font saat ini. Fungsi GetTabbedTextExtent menghitung lebar dan tinggi string karakter. Jika string berisi satu atau beberapa karakter tab, lebar string didasarkan pada array posisi tab-stop yang ditentukan. Fungsi GetTextExtentPoint32 menghitung lebar dan tinggi baris teks.

Jika perlu, sistem mensintesis font dengan mengubah bitmap karakter. Untuk mensintesis karakter dalam font tebal, sistem menggambar karakter dua kali: pada titik awal, dan sekali lagi satu piksel di sebelah kanan titik awal. Untuk mensintesis karakter dalam font miring, sistem menggambar dua baris piksel di bagian bawah sel karakter, memindahkan titik awal satu piksel ke kanan, menggambar dua baris berikutnya, dan melanjutkan hingga karakter telah digambar. Dengan menggeser piksel, setiap karakter tampak digeser ke kanan. Jumlah shear adalah fungsi dari tinggi karakter.

Salah satu cara untuk menulis baris teks yang berisi beberapa font adalah dengan menggunakan fungsi GetTextExtentPoint32 setelah setiap panggilan ke TextOut dan menambahkan panjang ke posisi saat ini. Contoh berikut menulis baris "Ini adalah string sampel." menggunakan karakter tebal untuk "Ini adalah", beralih ke karakter miring untuk "sampel", lalu kembali ke karakter tebal untuk "string." Setelah mencetak semua string, string memulihkan karakter default sistem.

int XIncrement; 
int YStart; 
TEXTMETRIC tm; 
HFONT hfntDefault, hfntItalic, hfntBold; 
SIZE sz; 
LPSTR lpszString1 = "This is a "; 
LPSTR lpszString2 = "sample "; 
LPSTR lpszString3 = "string."; 
HRESULT hr;
size_t * pcch;
 
// Create a bold and an italic logical font.  
 
hfntItalic = MyCreateFont(); 
hfntBold = MyCreateFont(); 
 
 
// Select the bold font and draw the first string  
// beginning at the specified point (XIncrement, YStart).  
 
XIncrement = 10; 
YStart = 50; 
hfntDefault = SelectObject(hdc, hfntBold); 
hr = StringCchLength(lpszString1, 11, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        }
TextOut(hdc, XIncrement, YStart, lpszString1, *pcch); 
 
// Compute the length of the first string and add  
// this value to the x-increment that is used for the  
// text-output operation.  

hr = StringCchLength(lpszString1, 11, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        } 
GetTextExtentPoint32(hdc, lpszString1, *pcch, &sz); 
XIncrement += sz.cx; 
 
// Retrieve the overhang value from the TEXTMETRIC  
// structure and subtract it from the x-increment.  
// (This is only necessary for non-TrueType raster  
// fonts.)  
 
GetTextMetrics(hdc, &tm); 
XIncrement -= tm.tmOverhang; 
 
// Select an italic font and draw the second string  
// beginning at the point (XIncrement, YStart).  
 
hfntBold = SelectObject(hdc, hfntItalic); 
GetTextMetrics(hdc, &tm); 
XIncrement -= tm.tmOverhang;
hr = StringCchLength(lpszString2, 8, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        } 
TextOut(hdc, XIncrement, YStart, lpszString2, *pcch); 
 
// Compute the length of the second string and add  
// this value to the x-increment that is used for the  
// text-output operation.  

hr = StringCchLength(lpszString2, 8, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        }  
GetTextExtentPoint32(hdc, lpszString2, *pcch, &sz); 
XIncrement += sz.cx; 
 
// Reselect the bold font and draw the third string  
// beginning at the point (XIncrement, YStart).  
 
SelectObject(hdc, hfntBold);
hr = StringCchLength(lpszString3, 8, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        }  
TextOut(hdc, XIncrement - tm.tmOverhang, YStart, lpszString3, 
            *pcch); 
 
// Reselect the original font.  
 
SelectObject(hdc, hfntDefault); 
 
// Delete the bold and italic fonts.  
 
DeleteObject(hfntItalic); 
DeleteObject(hfntBold); 

Dalam contoh ini, fungsi GetTextExtentPoint32 menginisialisasi anggota struktur SIZE dengan panjang dan tinggi string yang ditentukan. Fungsi GetTextMetrics mengambil overhang untuk font saat ini. Karena overhang adalah nol jika font adalah font TrueType, nilai overhang tidak mengubah penempatan string. Namun, untuk font raster, penting untuk menggunakan nilai overhang.

Overhang dikurangi dari string tebal sekali, untuk membawa karakter berikutnya lebih dekat ke akhir string jika font adalah font raster. Karena overhang mempengaruhi awal dan akhir string miring dalam font raster, glyph dimulai di sebelah kanan lokasi yang ditentukan dan berakhir di sebelah kiri titik akhir sel karakter terakhir. (Fungsi GetTextExtentPoint32 mengambil sejauh mana sel karakter, bukan tingkat glyph.) Untuk memperhitungkan overhang dalam string miring raster, contohnya mengurangi overhang sebelum menempatkan string dan menguranginya lagi sebelum menempatkan karakter berikutnya.

Fungsi SetTextJustification menambahkan ruang ekstra ke karakter pemisah dalam baris teks. Anda dapat menggunakan fungsi GetTextExtentPoint untuk menentukan sejauh mana string, lalu mengurangi batas tersebut dari jumlah total ruang yang harus ditempati baris, dan menggunakan fungsi SetTextJustification untuk mendistribusikan ruang ekstra di antara karakter pemisah dalam string. Fungsi SetTextCharacterExtra menambahkan ruang ekstra ke setiap sel karakter dalam font yang dipilih, termasuk karakter pemisah. (Anda dapat menggunakan fungsi GetTextCharacterExtra untuk menentukan jumlah ruang ekstra saat ini yang ditambahkan ke sel karakter; pengaturan defaultnya adalah nol.)

Anda dapat menempatkan karakter dengan presisi yang lebih besar dengan menggunakan fungsi GetCharWidth32 atau GetCharABCWidths untuk mengambil lebar karakter individual dalam font. Fungsi GetCharABCWidths lebih akurat daripada fungsi GetCharWidth32 , tetapi hanya dapat digunakan dengan font TrueType.

Penspasian ABC juga memungkinkan aplikasi untuk melakukan perataan teks yang sangat akurat. Misalnya, ketika aplikasi rata kanan font romawi raster tanpa menggunakan spasi ABC, lebar muka dihitung sebagai lebar karakter. Ini berarti ruang putih di sebelah kanan glyph dalam bitmap selaras, bukan glyph itu sendiri. Dengan menggunakan lebar ABC, aplikasi memiliki lebih banyak fleksibilitas dalam penempatan dan penghapusan spasi putih saat meratakan teks, karena aplikasi memiliki informasi yang memungkinkan aplikasi mengontrol spasi intercharacter dengan halus.