mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 13:32:45 +00:00 
			
		
		
		
	LibPDF: In Type0Font, read metrics /DW2 and /W2 for vertical text
Not used for anything yet.
This commit is contained in:
		
							parent
							
								
									ef5d7b685d
								
							
						
					
					
						commit
						b9a4689af3
					
				
					 3 changed files with 59 additions and 0 deletions
				
			
		|  | @ -52,6 +52,7 @@ | |||
|     X(D)                          \ | ||||
|     X(DCTDecode)                  \ | ||||
|     X(DW)                         \ | ||||
|     X(DW2)                        \ | ||||
|     X(DamagedRowsBeforeError)     \ | ||||
|     X(Decode)                     \ | ||||
|     X(DecodeParms)                \ | ||||
|  | @ -188,6 +189,7 @@ | |||
|     X(UserUnit)                   \ | ||||
|     X(V)                          \ | ||||
|     X(W)                          \ | ||||
|     X(W2)                         \ | ||||
|     X(WhitePoint)                 \ | ||||
|     X(Width)                      \ | ||||
|     X(Widths)                     \ | ||||
|  |  | |||
|  | @ -306,9 +306,56 @@ PDFErrorOr<void> Type0Font::initialize(Document* document, NonnullRefPtr<DictObj | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // "The default position vector and vertical displacement vector are specified by the DW2 entry in the CIDFont dictionary."
 | ||||
|     int default_position_vector_y = 880; | ||||
|     int default_displacement_vector_y = -1000; | ||||
|     if (descendant_font->contains(CommonNames::DW2)) { | ||||
|         auto widths_array = MUST(descendant_font->get_array(document, CommonNames::DW2)); | ||||
|         VERIFY(widths_array->size() == 2); | ||||
|         default_position_vector_y = widths_array->at(0).to_int(); | ||||
|         default_displacement_vector_y = widths_array->at(1).to_int(); | ||||
|     } | ||||
| 
 | ||||
|     // "The W2 array allows the definition of vertical metrics for individual CIDs."
 | ||||
|     HashMap<u16, VerticalMetric> vertical_metrics; | ||||
|     if (descendant_font->contains(CommonNames::W2)) { | ||||
|         auto widths_array = MUST(descendant_font->get_array(document, CommonNames::W2)); | ||||
|         Optional<u16> pending_code; | ||||
| 
 | ||||
|         for (size_t i = 0; i < widths_array->size(); i++) { | ||||
|             auto& value = widths_array->at(i); | ||||
|             if (!pending_code.has_value()) { | ||||
|                 pending_code = value.to_int(); | ||||
|             } else if (value.has_number()) { | ||||
|                 auto first_code = pending_code.release_value(); | ||||
|                 auto last_code = value.to_int(); | ||||
|                 auto vertical_displacement_vector_y = widths_array->at(i + 1).to_int(); | ||||
|                 auto position_vector_x = widths_array->at(i + 2).to_int(); | ||||
|                 auto position_vector_y = widths_array->at(i + 3).to_int(); | ||||
|                 i += 3; | ||||
| 
 | ||||
|                 for (u16 code = first_code; code <= last_code; code++) | ||||
|                     vertical_metrics.set(code, VerticalMetric { vertical_displacement_vector_y, position_vector_x, position_vector_y }); | ||||
|             } else { | ||||
|                 auto array = TRY(document->resolve_to<ArrayObject>(value)); | ||||
|                 VERIFY(array->size() % 3 == 0); | ||||
|                 auto code = pending_code.release_value(); | ||||
|                 for (size_t j = 0; j < array->size(); j += 3) { | ||||
|                     auto vertical_displacement_vector_y = array->at(j).to_int(); | ||||
|                     auto position_vector_x = array->at(j + 1).to_int(); | ||||
|                     auto position_vector_y = array->at(j + 2).to_int(); | ||||
|                     vertical_metrics.set(code++, VerticalMetric { vertical_displacement_vector_y, position_vector_x, position_vector_y }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     m_system_info = move(system_info); | ||||
|     m_widths = move(widths); | ||||
|     m_missing_width = default_width; | ||||
|     m_default_position_vector_y = default_position_vector_y; | ||||
|     m_default_displacement_vector_y = default_displacement_vector_y; | ||||
|     m_vertical_metrics = move(vertical_metrics); | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -40,6 +40,16 @@ private: | |||
|     CIDSystemInfo m_system_info; | ||||
|     HashMap<u16, u16> m_widths; | ||||
|     u16 m_missing_width; | ||||
| 
 | ||||
|     int m_default_position_vector_y; | ||||
|     int m_default_displacement_vector_y; | ||||
|     struct VerticalMetric { | ||||
|         int vertical_displacement_vector_y; | ||||
|         int position_vector_x; | ||||
|         int position_vector_y; | ||||
|     }; | ||||
|     HashMap<u16, VerticalMetric> m_vertical_metrics; | ||||
| 
 | ||||
|     OwnPtr<CIDFontType> m_cid_font_type; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nico Weber
						Nico Weber