diff --git a/libs/androidfw/NinePatch.cpp b/libs/androidfw/NinePatch.cpp
new file mode 100644
index 0000000..1fdbebf
--- /dev/null
+++ b/libs/androidfw/NinePatch.cpp
@@ -0,0 +1,682 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "androidfw/Image.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/StringPiece.h"
+
+using android::StringPiece;
+
+namespace android {
+
+// Colors in the format 0xAARRGGBB (the way 9-patch expects it).
+constexpr static const uint32_t kColorOpaqueWhite = 0xffffffffu;
+constexpr static const uint32_t kColorOpaqueBlack = 0xff000000u;
+constexpr static const uint32_t kColorOpaqueRed = 0xffff0000u;
+
+constexpr static const uint32_t kPrimaryColor = kColorOpaqueBlack;
+constexpr static const uint32_t kSecondaryColor = kColorOpaqueRed;
+
+/**
+ * Returns the alpha value encoded in the 0xAARRGBB encoded pixel.
+ */
+static uint32_t get_alpha(uint32_t color);
+
+/**
+ * Determines whether a color on an ImageLine is valid.
+ * A 9patch image may use a transparent color as neutral,
+ * or a fully opaque white color as neutral, based on the
+ * pixel color at (0,0) of the image. One or the other is fine,
+ * but we need to ensure consistency throughout the image.
+ */
+class ColorValidator {
+ public:
+  virtual ~ColorValidator() = default;
+
+  /**
+   * Returns true if the color specified is a neutral color
+   * (no padding, stretching, or optical bounds).
+   */
+  virtual bool IsNeutralColor(uint32_t color) const = 0;
+
+  /**
+   * Returns true if the color is either a neutral color
+   * or one denoting padding, stretching, or optical bounds.
+   */
+  bool IsValidColor(uint32_t color) const {
+    switch (color) {
+      case kPrimaryColor:
+      case kSecondaryColor:
+        return true;
+    }
+    return IsNeutralColor(color);
+  }
+};
+
+// Walks an ImageLine and records Ranges of primary and secondary colors.
+// The primary color is black and is used to denote a padding or stretching
+// range,
+// depending on which border we're iterating over.
+// The secondary color is red and is used to denote optical bounds.
+//
+// An ImageLine is a templated-interface that would look something like this if
+// it
+// were polymorphic:
+//
+// class ImageLine {
+// public:
+//      virtual int32_t GetLength() const = 0;
+//      virtual uint32_t GetColor(int32_t idx) const = 0;
+// };
+//
+template <typename ImageLine>
+static bool FillRanges(const ImageLine* image_line, const ColorValidator* color_validator,
+                       std::vector<Range>* primary_ranges, std::vector<Range>* secondary_ranges,
+                       std::string* out_err) {
+  const int32_t length = image_line->GetLength();
+
+  uint32_t last_color = 0xffffffffu;
+  for (int32_t idx = 1; idx < length - 1; idx++) {
+    const uint32_t color = image_line->GetColor(idx);
+    if (!color_validator->IsValidColor(color)) {
+      *out_err = "found an invalid color";
+      return false;
+    }
+
+    if (color != last_color) {
+      // We are ending a range. Which range?
+      // note: encode the x offset without the final 1 pixel border.
+      if (last_color == kPrimaryColor) {
+        primary_ranges->back().end = idx - 1;
+      } else if (last_color == kSecondaryColor) {
+        secondary_ranges->back().end = idx - 1;
+      }
+
+      // We are starting a range. Which range?
+      // note: encode the x offset without the final 1 pixel border.
+      if (color == kPrimaryColor) {
+        primary_ranges->push_back(Range(idx - 1, length - 2));
+      } else if (color == kSecondaryColor) {
+        secondary_ranges->push_back(Range(idx - 1, length - 2));
+      }
+      last_color = color;
+    }
+  }
+  return true;
+}
+
+/**
+ * Iterates over a row in an image. Implements the templated ImageLine
+ * interface.
+ */
+class HorizontalImageLine {
+ public:
+  explicit HorizontalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset, int32_t length)
+      : rows_(rows), xoffset_(xoffset), yoffset_(yoffset), length_(length) {
+  }
+
+  inline int32_t GetLength() const {
+    return length_;
+  }
+
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_] + (idx + xoffset_) * 4);
+  }
+
+ private:
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, length_;
+
+  DISALLOW_COPY_AND_ASSIGN(HorizontalImageLine);
+};
+
+/**
+ * Iterates over a column in an image. Implements the templated ImageLine
+ * interface.
+ */
+class VerticalImageLine {
+ public:
+  explicit VerticalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset, int32_t length)
+      : rows_(rows), xoffset_(xoffset), yoffset_(yoffset), length_(length) {
+  }
+
+  inline int32_t GetLength() const {
+    return length_;
+  }
+
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_ + idx] + (xoffset_ * 4));
+  }
+
+ private:
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, length_;
+
+  DISALLOW_COPY_AND_ASSIGN(VerticalImageLine);
+};
+
+class DiagonalImageLine {
+ public:
+  explicit DiagonalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset, int32_t xstep,
+                             int32_t ystep, int32_t length)
+      : rows_(rows),
+        xoffset_(xoffset),
+        yoffset_(yoffset),
+        xstep_(xstep),
+        ystep_(ystep),
+        length_(length) {
+  }
+
+  inline int32_t GetLength() const {
+    return length_;
+  }
+
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_ + (idx * ystep_)] + ((idx + xoffset_) * xstep_) * 4);
+  }
+
+ private:
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, xstep_, ystep_, length_;
+
+  DISALLOW_COPY_AND_ASSIGN(DiagonalImageLine);
+};
+
+class TransparentNeutralColorValidator : public ColorValidator {
+ public:
+  bool IsNeutralColor(uint32_t color) const override {
+    return get_alpha(color) == 0;
+  }
+};
+
+class WhiteNeutralColorValidator : public ColorValidator {
+ public:
+  bool IsNeutralColor(uint32_t color) const override {
+    return color == kColorOpaqueWhite;
+  }
+};
+
+inline static uint32_t get_alpha(uint32_t color) {
+  return (color & 0xff000000u) >> 24;
+}
+
+static bool PopulateBounds(const std::vector<Range>& padding,
+                           const std::vector<Range>& layout_bounds,
+                           const std::vector<Range>& stretch_regions, const int32_t length,
+                           int32_t* padding_start, int32_t* padding_end, int32_t* layout_start,
+                           int32_t* layout_end, StringPiece edge_name, std::string* out_err) {
+  if (padding.size() > 1) {
+    std::stringstream err_stream;
+    err_stream << "too many padding sections on " << edge_name << " border";
+    *out_err = err_stream.str();
+    return false;
+  }
+
+  *padding_start = 0;
+  *padding_end = 0;
+  if (!padding.empty()) {
+    const Range& range = padding.front();
+    *padding_start = range.start;
+    *padding_end = length - range.end;
+  } else if (!stretch_regions.empty()) {
+    // No padding was defined. Compute the padding from the first and last
+    // stretch regions.
+    *padding_start = stretch_regions.front().start;
+    *padding_end = length - stretch_regions.back().end;
+  }
+
+  if (layout_bounds.size() > 2) {
+    std::stringstream err_stream;
+    err_stream << "too many layout bounds sections on " << edge_name << " border";
+    *out_err = err_stream.str();
+    return false;
+  }
+
+  *layout_start = 0;
+  *layout_end = 0;
+  if (layout_bounds.size() >= 1) {
+    const Range& range = layout_bounds.front();
+    // If there is only one layout bound segment, it might not start at 0, but
+    // then it should
+    // end at length.
+    if (range.start != 0 && range.end != length) {
+      std::stringstream err_stream;
+      err_stream << "layout bounds on " << edge_name << " border must start at edge";
+      *out_err = err_stream.str();
+      return false;
+    }
+    *layout_start = range.end;
+
+    if (layout_bounds.size() >= 2) {
+      const Range& range = layout_bounds.back();
+      if (range.end != length) {
+        std::stringstream err_stream;
+        err_stream << "layout bounds on " << edge_name << " border must start at edge";
+        *out_err = err_stream.str();
+        return false;
+      }
+      *layout_end = length - range.start;
+    }
+  }
+  return true;
+}
+
+static int32_t CalculateSegmentCount(const std::vector<Range>& stretch_regions, int32_t length) {
+  if (stretch_regions.size() == 0) {
+    return 0;
+  }
+
+  const bool start_is_fixed = stretch_regions.front().start != 0;
+  const bool end_is_fixed = stretch_regions.back().end != length;
+  int32_t modifier = 0;
+  if (start_is_fixed && end_is_fixed) {
+    modifier = 1;
+  } else if (!start_is_fixed && !end_is_fixed) {
+    modifier = -1;
+  }
+  return static_cast<int32_t>(stretch_regions.size()) * 2 + modifier;
+}
+
+static uint32_t GetRegionColor(uint8_t** rows, const Bounds& region) {
+  // Sample the first pixel to compare against.
+  const uint32_t expected_color = NinePatch::PackRGBA(rows[region.top] + region.left * 4);
+  for (int32_t y = region.top; y < region.bottom; y++) {
+    const uint8_t* row = rows[y];
+    for (int32_t x = region.left; x < region.right; x++) {
+      const uint32_t color = NinePatch::PackRGBA(row + x * 4);
+      if (get_alpha(color) == 0) {
+        // The color is transparent.
+        // If the expectedColor is not transparent, NO_COLOR.
+        if (get_alpha(expected_color) != 0) {
+          return android::Res_png_9patch::NO_COLOR;
+        }
+      } else if (color != expected_color) {
+        return android::Res_png_9patch::NO_COLOR;
+      }
+    }
+  }
+
+  if (get_alpha(expected_color) == 0) {
+    return android::Res_png_9patch::TRANSPARENT_COLOR;
+  }
+  return expected_color;
+}
+
+// Fills out_colors with each 9-patch section's color. If the whole section is
+// transparent,
+// it gets the special TRANSPARENT color. If the whole section is the same
+// color, it is assigned
+// that color. Otherwise it gets the special NO_COLOR color.
+//
+// Note that the rows contain the 9-patch 1px border, and the indices in the
+// stretch regions are
+// already offset to exclude the border. This means that each time the rows are
+// accessed,
+// the indices must be offset by 1.
+//
+// width and height also include the 9-patch 1px border.
+static void CalculateRegionColors(uint8_t** rows,
+                                  const std::vector<Range>& horizontal_stretch_regions,
+                                  const std::vector<Range>& vertical_stretch_regions,
+                                  const int32_t width, const int32_t height,
+                                  std::vector<uint32_t>* out_colors) {
+  int32_t next_top = 0;
+  Bounds bounds;
+  auto row_iter = vertical_stretch_regions.begin();
+  while (next_top != height) {
+    if (row_iter != vertical_stretch_regions.end()) {
+      if (next_top != row_iter->start) {
+        // This is a fixed segment.
+        // Offset the bounds by 1 to accommodate the border.
+        bounds.top = next_top + 1;
+        bounds.bottom = row_iter->start + 1;
+        next_top = row_iter->start;
+      } else {
+        // This is a stretchy segment.
+        // Offset the bounds by 1 to accommodate the border.
+        bounds.top = row_iter->start + 1;
+        bounds.bottom = row_iter->end + 1;
+        next_top = row_iter->end;
+        ++row_iter;
+      }
+    } else {
+      // This is the end, fixed section.
+      // Offset the bounds by 1 to accommodate the border.
+      bounds.top = next_top + 1;
+      bounds.bottom = height + 1;
+      next_top = height;
+    }
+
+    int32_t next_left = 0;
+    auto col_iter = horizontal_stretch_regions.begin();
+    while (next_left != width) {
+      if (col_iter != horizontal_stretch_regions.end()) {
+        if (next_left != col_iter->start) {
+          // This is a fixed segment.
+          // Offset the bounds by 1 to accommodate the border.
+          bounds.left = next_left + 1;
+          bounds.right = col_iter->start + 1;
+          next_left = col_iter->start;
+        } else {
+          // This is a stretchy segment.
+          // Offset the bounds by 1 to accommodate the border.
+          bounds.left = col_iter->start + 1;
+          bounds.right = col_iter->end + 1;
+          next_left = col_iter->end;
+          ++col_iter;
+        }
+      } else {
+        // This is the end, fixed section.
+        // Offset the bounds by 1 to accommodate the border.
+        bounds.left = next_left + 1;
+        bounds.right = width + 1;
+        next_left = width;
+      }
+      out_colors->push_back(GetRegionColor(rows, bounds));
+    }
+  }
+}
+
+// Calculates the insets of a row/column of pixels based on where the largest
+// alpha value begins
+// (on both sides).
+template <typename ImageLine>
+static void FindOutlineInsets(const ImageLine* image_line, int32_t* out_start, int32_t* out_end) {
+  *out_start = 0;
+  *out_end = 0;
+
+  const int32_t length = image_line->GetLength();
+  if (length < 3) {
+    return;
+  }
+
+  // If the length is odd, we want both sides to process the center pixel,
+  // so we use two different midpoints (to account for < and <= in the different
+  // loops).
+  const int32_t mid2 = length / 2;
+  const int32_t mid1 = mid2 + (length % 2);
+
+  uint32_t max_alpha = 0;
+  for (int32_t i = 0; i < mid1 && max_alpha != 0xff; i++) {
+    uint32_t alpha = get_alpha(image_line->GetColor(i));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
+      *out_start = i;
+    }
+  }
+
+  max_alpha = 0;
+  for (int32_t i = length - 1; i >= mid2 && max_alpha != 0xff; i--) {
+    uint32_t alpha = get_alpha(image_line->GetColor(i));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
+      *out_end = length - (i + 1);
+    }
+  }
+  return;
+}
+
+template <typename ImageLine>
+static uint32_t FindMaxAlpha(const ImageLine* image_line) {
+  const int32_t length = image_line->GetLength();
+  uint32_t max_alpha = 0;
+  for (int32_t idx = 0; idx < length && max_alpha != 0xff; idx++) {
+    uint32_t alpha = get_alpha(image_line->GetColor(idx));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
+    }
+  }
+  return max_alpha;
+}
+
+// Pack the pixels in as 0xAARRGGBB (as 9-patch expects it).
+uint32_t NinePatch::PackRGBA(const uint8_t* pixel) {
+  return (pixel[3] << 24) | (pixel[0] << 16) | (pixel[1] << 8) | pixel[2];
+}
+
+std::unique_ptr<NinePatch> NinePatch::Create(uint8_t** rows, const int32_t width,
+                                             const int32_t height, std::string* out_err) {
+  if (width < 3 || height < 3) {
+    *out_err = "image must be at least 3x3 (1x1 image with 1 pixel border)";
+    return {};
+  }
+
+  std::vector<Range> horizontal_padding;
+  std::vector<Range> horizontal_layout_bounds;
+  std::vector<Range> vertical_padding;
+  std::vector<Range> vertical_layout_bounds;
+  std::vector<Range> unexpected_ranges;
+  std::unique_ptr<ColorValidator> color_validator;
+
+  if (rows[0][3] == 0) {
+    color_validator = std::make_unique<TransparentNeutralColorValidator>();
+  } else if (PackRGBA(rows[0]) == kColorOpaqueWhite) {
+    color_validator = std::make_unique<WhiteNeutralColorValidator>();
+  } else {
+    *out_err = "top-left corner pixel must be either opaque white or transparent";
+    return {};
+  }
+
+  // Private constructor, can't use make_unique.
+  auto nine_patch = std::unique_ptr<NinePatch>(new NinePatch());
+
+  HorizontalImageLine top_row(rows, 0, 0, width);
+  if (!FillRanges(&top_row, color_validator.get(), &nine_patch->horizontal_stretch_regions,
+                  &unexpected_ranges, out_err)) {
+    return {};
+  }
+
+  if (!unexpected_ranges.empty()) {
+    const Range& range = unexpected_ranges[0];
+    std::stringstream err_stream;
+    err_stream << "found unexpected optical bounds (red pixel) on top border "
+               << "at x=" << range.start + 1;
+    *out_err = err_stream.str();
+    return {};
+  }
+
+  VerticalImageLine left_col(rows, 0, 0, height);
+  if (!FillRanges(&left_col, color_validator.get(), &nine_patch->vertical_stretch_regions,
+                  &unexpected_ranges, out_err)) {
+    return {};
+  }
+
+  if (!unexpected_ranges.empty()) {
+    const Range& range = unexpected_ranges[0];
+    std::stringstream err_stream;
+    err_stream << "found unexpected optical bounds (red pixel) on left border "
+               << "at y=" << range.start + 1;
+    return {};
+  }
+
+  HorizontalImageLine bottom_row(rows, 0, height - 1, width);
+  if (!FillRanges(&bottom_row, color_validator.get(), &horizontal_padding,
+                  &horizontal_layout_bounds, out_err)) {
+    return {};
+  }
+
+  if (!PopulateBounds(horizontal_padding, horizontal_layout_bounds,
+                      nine_patch->horizontal_stretch_regions, width - 2, &nine_patch->padding.left,
+                      &nine_patch->padding.right, &nine_patch->layout_bounds.left,
+                      &nine_patch->layout_bounds.right, "bottom", out_err)) {
+    return {};
+  }
+
+  VerticalImageLine right_col(rows, width - 1, 0, height);
+  if (!FillRanges(&right_col, color_validator.get(), &vertical_padding, &vertical_layout_bounds,
+                  out_err)) {
+    return {};
+  }
+
+  if (!PopulateBounds(vertical_padding, vertical_layout_bounds,
+                      nine_patch->vertical_stretch_regions, height - 2, &nine_patch->padding.top,
+                      &nine_patch->padding.bottom, &nine_patch->layout_bounds.top,
+                      &nine_patch->layout_bounds.bottom, "right", out_err)) {
+    return {};
+  }
+
+  // Fill the region colors of the 9-patch.
+  const int32_t num_rows = CalculateSegmentCount(nine_patch->horizontal_stretch_regions, width - 2);
+  const int32_t num_cols = CalculateSegmentCount(nine_patch->vertical_stretch_regions, height - 2);
+  if ((int64_t)num_rows * (int64_t)num_cols > 0x7f) {
+    *out_err = "too many regions in 9-patch";
+    return {};
+  }
+
+  nine_patch->region_colors.reserve(num_rows * num_cols);
+  CalculateRegionColors(rows, nine_patch->horizontal_stretch_regions,
+                        nine_patch->vertical_stretch_regions, width - 2, height - 2,
+                        &nine_patch->region_colors);
+
+  // Compute the outline based on opacity.
+
+  // Find left and right extent of 9-patch content on center row.
+  HorizontalImageLine mid_row(rows, 1, height / 2, width - 2);
+  FindOutlineInsets(&mid_row, &nine_patch->outline.left, &nine_patch->outline.right);
+
+  // Find top and bottom extent of 9-patch content on center column.
+  VerticalImageLine mid_col(rows, width / 2, 1, height - 2);
+  FindOutlineInsets(&mid_col, &nine_patch->outline.top, &nine_patch->outline.bottom);
+
+  const int32_t outline_width = (width - 2) - nine_patch->outline.left - nine_patch->outline.right;
+  const int32_t outline_height =
+      (height - 2) - nine_patch->outline.top - nine_patch->outline.bottom;
+
+  // Find the largest alpha value within the outline area.
+  HorizontalImageLine outline_mid_row(rows, 1 + nine_patch->outline.left,
+                                      1 + nine_patch->outline.top + (outline_height / 2),
+                                      outline_width);
+  VerticalImageLine outline_mid_col(rows, 1 + nine_patch->outline.left + (outline_width / 2),
+                                    1 + nine_patch->outline.top, outline_height);
+  nine_patch->outline_alpha =
+      std::max(FindMaxAlpha(&outline_mid_row), FindMaxAlpha(&outline_mid_col));
+
+  // Assuming the image is a round rect, compute the radius by marching
+  // diagonally from the top left corner towards the center.
+  DiagonalImageLine diagonal(rows, 1 + nine_patch->outline.left, 1 + nine_patch->outline.top, 1, 1,
+                             std::min(outline_width, outline_height));
+  int32_t top_left, bottom_right;
+  FindOutlineInsets(&diagonal, &top_left, &bottom_right);
+
+  /* Determine source radius based upon inset:
+   *     sqrt(r^2 + r^2) = sqrt(i^2 + i^2) + r
+   *     sqrt(2) * r = sqrt(2) * i + r
+   *     (sqrt(2) - 1) * r = sqrt(2) * i
+   *     r = sqrt(2) / (sqrt(2) - 1) * i
+   */
+  nine_patch->outline_radius = 3.4142f * top_left;
+  return nine_patch;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::SerializeBase(size_t* outLen) const {
+  android::Res_png_9patch data;
+  data.numXDivs = static_cast<uint8_t>(horizontal_stretch_regions.size()) * 2;
+  data.numYDivs = static_cast<uint8_t>(vertical_stretch_regions.size()) * 2;
+  data.numColors = static_cast<uint8_t>(region_colors.size());
+  data.paddingLeft = padding.left;
+  data.paddingRight = padding.right;
+  data.paddingTop = padding.top;
+  data.paddingBottom = padding.bottom;
+
+  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[data.serializedSize()]);
+  android::Res_png_9patch::serialize(data, (const int32_t*)horizontal_stretch_regions.data(),
+                                     (const int32_t*)vertical_stretch_regions.data(),
+                                     region_colors.data(), buffer.get());
+  // Convert to file endianness.
+  reinterpret_cast<android::Res_png_9patch*>(buffer.get())->deviceToFile();
+
+  *outLen = data.serializedSize();
+  return buffer;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::SerializeLayoutBounds(size_t* out_len) const {
+  size_t chunk_len = sizeof(uint32_t) * 4;
+  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunk_len]);
+  uint8_t* cursor = buffer.get();
+
+  memcpy(cursor, &layout_bounds.left, sizeof(layout_bounds.left));
+  cursor += sizeof(layout_bounds.left);
+
+  memcpy(cursor, &layout_bounds.top, sizeof(layout_bounds.top));
+  cursor += sizeof(layout_bounds.top);
+
+  memcpy(cursor, &layout_bounds.right, sizeof(layout_bounds.right));
+  cursor += sizeof(layout_bounds.right);
+
+  memcpy(cursor, &layout_bounds.bottom, sizeof(layout_bounds.bottom));
+  cursor += sizeof(layout_bounds.bottom);
+
+  *out_len = chunk_len;
+  return buffer;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::SerializeRoundedRectOutline(size_t* out_len) const {
+  size_t chunk_len = sizeof(uint32_t) * 6;
+  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunk_len]);
+  uint8_t* cursor = buffer.get();
+
+  memcpy(cursor, &outline.left, sizeof(outline.left));
+  cursor += sizeof(outline.left);
+
+  memcpy(cursor, &outline.top, sizeof(outline.top));
+  cursor += sizeof(outline.top);
+
+  memcpy(cursor, &outline.right, sizeof(outline.right));
+  cursor += sizeof(outline.right);
+
+  memcpy(cursor, &outline.bottom, sizeof(outline.bottom));
+  cursor += sizeof(outline.bottom);
+
+  *((float*)cursor) = outline_radius;
+  cursor += sizeof(outline_radius);
+
+  *((uint32_t*)cursor) = outline_alpha;
+
+  *out_len = chunk_len;
+  return buffer;
+}
+
+::std::ostream& operator<<(::std::ostream& out, const Range& range) {
+  return out << "[" << range.start << ", " << range.end << ")";
+}
+
+::std::ostream& operator<<(::std::ostream& out, const Bounds& bounds) {
+  return out << "l=" << bounds.left << " t=" << bounds.top << " r=" << bounds.right
+             << " b=" << bounds.bottom;
+}
+
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
+  for (int i = 0; i < v.size(); ++i) {
+    os << v[i];
+    if (i != v.size() - 1) os << " ";
+  }
+  return os;
+}
+
+::std::ostream& operator<<(::std::ostream& out, const NinePatch& nine_patch) {
+  return out << "horizontalStretch:" << nine_patch.horizontal_stretch_regions
+             << " verticalStretch:" << nine_patch.vertical_stretch_regions
+             << " padding: " << nine_patch.padding << ", bounds: " << nine_patch.layout_bounds
+             << ", outline: " << nine_patch.outline << " rad=" << nine_patch.outline_radius
+             << " alpha=" << nine_patch.outline_alpha;
+}
+
+}  // namespace android
