From de643df7bdbc1580ad7ea1604a848f73a8c78783 Mon Sep 17 00:00:00 2001 From: niklaspandersson Date: Tue, 20 Aug 2013 10:15:32 +0200 Subject: [PATCH] * psd: support for extracting scaling-data of text-layer, and extracting sheet-color meta-data --- modules/psd/layer.cpp | 40 ++++++++++++++++++++++-------- modules/psd/layer.h | 2 ++ modules/psd/misc.h | 5 ++++ modules/psd/psd_scene_producer.cpp | 4 +++ test/psd-test/psd-test.cpp | 4 +-- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/modules/psd/layer.cpp b/modules/psd/layer.cpp index 8369c5d0f..40906e0ae 100644 --- a/modules/psd/layer.cpp +++ b/modules/psd/layer.cpp @@ -22,6 +22,7 @@ #include "layer.h" #include "doc.h" #include "descriptor.h" +#include #include "util\pdf_reader.h" #include @@ -74,7 +75,7 @@ struct layer::impl { friend class layer; - impl() : blend_mode_(InvalidBlendMode), link_group_id_(0), opacity_(255), baseClipping_(false), flags_(0), protection_flags_(0), masks_count_(0) + impl() : blend_mode_(InvalidBlendMode), link_group_id_(0), opacity_(255), sheet_color_(0), baseClipping_(false), flags_(0), protection_flags_(0), masks_count_(0), text_scale_(1.0f) {} private: @@ -82,11 +83,13 @@ private: blend_mode blend_mode_; int link_group_id_; unsigned char opacity_; + unsigned short sheet_color_; bool baseClipping_; unsigned char flags_; int protection_flags_; std::wstring name_; char masks_count_; + float text_scale_; rect vector_mask_; layer::layer_mask_info mask_; @@ -191,6 +194,10 @@ public: case 'shmd': //metadata read_metadata(stream, doc); break; + + case 'lclr': + sheet_color_ = stream.read_short(); + break; case 'lyvr': //layer version break; @@ -212,9 +219,10 @@ public: break; } } - catch(PSDFileFormatException&) + catch(PSDFileFormatException& ex) { //ignore failed chunks silently + CASPAR_LOG(warning) << ex.what(); } stream.set_position(end_of_chunk); @@ -227,7 +235,7 @@ public: descriptor solid_descriptor; if(!solid_descriptor.populate(stream)) - throw PSDFileFormatException(); + throw PSDFileFormatException("Failed to read solid color data"); else { solid_color_.red = static_cast(solid_descriptor.items().get(L"Clr .Rd ", 0.0) + 0.5); @@ -326,16 +334,20 @@ public: double yy = stream.read_double(); double tx = stream.read_double(); double ty = stream.read_double(); + if(xx != yy || (xy != 0 && yx != 0)) + throw PSDFileFormatException("Rotation and non-uniform scaling of dynamic textfields is not supported yet"); + + text_scale_ = static_cast(xx); if(stream.read_short() != 50) //"text version" should be 50 - throw PSDFileFormatException(); + throw PSDFileFormatException("invalid text version"); if(stream.read_long() != 16) //"descriptor version" should be 16 - throw PSDFileFormatException(); + throw PSDFileFormatException("Invalid descriptor version while reading text-data"); descriptor text_descriptor; if(!text_descriptor.populate(stream)) - throw PSDFileFormatException(); + throw PSDFileFormatException("Failed to read text-info"); else { auto text_info = text_descriptor.items().get_optional(L"EngineData"); @@ -347,16 +359,21 @@ public: } if(stream.read_short() != 1) //"warp version" should be 1 - throw PSDFileFormatException(); + throw PSDFileFormatException("invalid warp version"); if(stream.read_long() != 16) //"descriptor version" should be 16 - throw PSDFileFormatException(); + throw PSDFileFormatException("Invalid descriptor version while reading text warp-data"); descriptor warp_descriptor; if(!warp_descriptor.populate(stream)) - throw PSDFileFormatException(); + throw PSDFileFormatException("Failed to read text warp-data"); else - stream.discard_bytes(4*8); //top, left, right, bottom + { + double w_top = stream.read_double(); + double w_left = stream.read_double(); + double w_right = stream.read_double(); + double w_bottom = stream.read_double(); + } } //TODO: implement @@ -543,11 +560,12 @@ void layer::read_channel_data(BEFileInputStream& stream) { impl_->read_channel_d const std::wstring& layer::name() const { return impl_->name_; } unsigned char layer::opacity() const { return impl_->opacity_; } +unsigned short layer::sheet_color() const { return impl_->sheet_color_; } bool layer::is_visible() { return (impl_->flags_ & 2) == 0; } //the (PSD file-format) documentation is is saying the opposite but what the heck bool layer::is_position_protected() { return (impl_->protection_flags_& 4) == 4; } - +float layer::text_scale() const { return impl_->text_scale_; } bool layer::is_text() const { return !impl_->text_layer_info_.empty(); } const boost::property_tree::wptree& layer::text_data() const { return impl_->text_layer_info_; } diff --git a/modules/psd/layer.h b/modules/psd/layer.h index 5677e02ab..d094b679e 100644 --- a/modules/psd/layer.h +++ b/modules/psd/layer.h @@ -74,9 +74,11 @@ public: const std::wstring& name() const; unsigned char opacity() const; + unsigned short sheet_color() const; bool is_visible(); bool is_position_protected(); + float text_scale() const; bool is_text() const; const boost::property_tree::wptree& text_data() const; diff --git a/modules/psd/misc.h b/modules/psd/misc.h index 9651f6bec..886c91bbe 100644 --- a/modules/psd/misc.h +++ b/modules/psd/misc.h @@ -75,6 +75,11 @@ struct rect class PSDFileFormatException : public std::exception { public: + PSDFileFormatException() : std::exception() + {} + explicit PSDFileFormatException(const char* msg) : std::exception(msg) + {} + virtual ~PSDFileFormatException() {} virtual const char *what() const diff --git a/modules/psd/psd_scene_producer.cpp b/modules/psd/psd_scene_producer.cpp index e5fde8677..9d5442bee 100644 --- a/modules/psd/psd_scene_producer.cpp +++ b/modules/psd/psd_scene_producer.cpp @@ -55,6 +55,10 @@ core::text::text_info get_text_info(const boost::property_tree::wptree& ptree) core::text::text_info result; int font_index = ptree.get(L"EngineDict.StyleRun.RunArray..StyleSheet.StyleSheetData.Font", 0); result.size = ptree.get(L"EngineDict.StyleRun.RunArray..StyleSheet.StyleSheetData.FontSize", 30.0f); + //result.leading = ptree.get(L"EngineDict.StyleRun.RunArray..StyleSheet.StyleSheetData.Leading", 0); + //result.tracking = ptree.get(L"EngineDict.StyleRun.RunArray..StyleSheet.StyleSheetData.Tracking", 0); + //result.baselineshift = ptree.get(L"EngineDict.StyleRun.RunArray..StyleSheet.StyleSheetData.BaselineShift", 0); + //result.kerning = ptree.get(L"EngineDict.StyleRun.RunArray..StyleSheet.StyleSheetData.Kerning", 0); int child_index = 0; auto color_node = ptree.get_child(L"EngineDict.StyleRun.RunArray..StyleSheet.StyleSheetData.FillColor.Values"); diff --git a/test/psd-test/psd-test.cpp b/test/psd-test/psd-test.cpp index e302f06a9..3888f8876 100644 --- a/test/psd-test/psd-test.cpp +++ b/test/psd-test/psd-test.cpp @@ -46,8 +46,8 @@ int _tmain(int argc, _TCHAR* argv[]) if(layer->is_text()) { trace << L" " << std::endl; - //boost::property_tree::xml_writer_settings w(' ', 3); - //boost::property_tree::write_xml(trace, (*it)->text_data(), w); + boost::property_tree::xml_writer_settings w(' ', 3); + boost::property_tree::write_xml(trace, (*it)->text_data(), w); } if(layer->has_timeline()) { -- 2.39.2